我正在尝试创建一个类来下载图像,存储它然后将其作为Drawable
返回。该文件不需要多次下载,但只是第一次下载。
这是我的班级:
package com.ishan.drawabletest;
..........................
public class DrawableProvider extends ContextWrapper{
Drawable resultDrawable;
public DrawableProvider(Context base) {
super(base);
}
public Drawable get(final String fileURL) {
// File name that is being downloaded
String downloadedFileName = fileURL.substring(fileURL.lastIndexOf("/")+1);
final String imagePath = getFilesDir() + "/" + downloadedFileName;
// Checking if the file exists or not
final File file = new File(imagePath);
if(file.exists()) {
// The image already exists, have to only return it by converting into drawable
resultDrawable = Drawable.createFromPath(imagePath);
return resultDrawable;
} else {
// The image doesn't exists already.
Thread t = new Thread() {
@Override
public void run() {
try {
// Downloading the image here
..................
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
resultDrawable = Drawable.createFromPath(imagePath);
}
};
t.start();
// Waiting for the thread to finish before returning using join
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return resultDrawable;
}
}
}
这个类被调用并像这样使用。 :
ImageView permanentImageView = (ImageView) findViewById(R.id.permaImageView);
DrawableProvider dp = new DrawableProvider(this);
permanentImageView.setImageDrawable(dp.get("http://youthvibe2014server.herokuapp.com/public/selenaGomez.jpg"));
对于图像已经可用的情况,它可以正常工作。问题是,如果我不等待(即,如果删除了连接)线程完成并立即返回,则屏幕不包含图像甚至不是默认图像(以XML定义)哪个应该在那里,直到下载完成。
看起来像这样。
我想是这样的,因为我的get
方法没有等待线程完成并返回null
,因此permanentImageView
包含null
。< / p>
但是如果我等待让线程完成。屏幕最终显示下载的图像,但暂时它变为空白,看起来像这样。 :
我想这是因为当我等待线程完成时,我的UI线程暂时被阻止。
我无法使用AsyncTask
,因为我正在扩展ContextWrapper
,因此无法扩展AsyncTask
。有没有办法等待我的线程完成然后返回而不阻塞我的UI线程?
答案 0 :(得分:1)
我无法使用AsyncTask,因为我正在扩展ContextWrapper,因此无法扩展AsyncTask。
所以,摆脱ContextWrapper
。无论如何,您并未将其用于预期目的。继承它并没有对你做任何有用的事情,所以继承自AsyncTask
。
或者,更好的是,使用任何一个看似无限数量的现有库来完成这项工作。
答案 1 :(得分:0)
一种可能的解决方案:将活动发送到您的班级并使用
activity.RunOnUiThread(Runnable runnable)
在runnable中,您可以像回调一样通知用户。 你可以从后台线程中调用这个函数。
下载图像后
resultDrawable = Drawable.createFromPath(imagePath);
放置RunOnUIThread并创建对Fragment / Activity的回调。此回调从UI中获取Image已准备就绪,因此您可以将其放在ImageView中。
例如创建一个名为
的函数public Drawable getDrawable() {
return resultDrawable;
}
回调中的使用此函数将Image放在ImageView中。