我正在开发一个实现包含图像的自定义 ListView 的应用程序。我能够让 ListView 下载和缓存图像,但我想将下载移动到一个单独的线程上。为此,我创建了一个 CachedLogoDownloader 类,其目标是异步下载图像并将它们保存在内存中,以便稍后由自定义 Adapter 类访问。
问题在于线程占据了整个 UI。即使 run() 中的代码只是一个“thread.sleep()”,只要出现对 Logo 图像的请求,UI 就会停止。同样,在 run() 中放置一个无限循环会导致程序无限期挂起。
class CachedLogoDownloader{
private HashMap<String, Bitmap> cache = new HashMap<String, Bitmap>();
Context context;
ArrayList<String> FIDs;
Thread runner;
public CachedLogoDownloader(Context inContext){
this.context = inContext;
//list of company logos (by FID) to be downloaded
FIDs = new ArrayList<String>();
//asynchronous downloader thread (single thread for lower-end devices. Shouldn't be much slower to get the images, though)
runner = new Thread(new Runnable() {
public void run() {
for(String FID:FIDs){
Log.d(Cloud.DEBUG_TAG, "Icon Runnable for: " + FID);
Bitmap tempImage = Cloud.lookupIcon(context, FID);
cache.put(FID, tempImage);
FIDs.remove(FID);
}
}
});
}
public Bitmap getLogo(Company aCompany){
String currentFID = aCompany.getFID();
//if the image has already been cached, return the cached image
if(cache.containsKey(currentFID))
{
return cache.get(currentFID);
}
else
{
//add the logo to the list of logos to be downloaded
FIDs.add(currentFID);
//if the downloader thread completed (or hasn't started yet) make it download stuff.
if(!runner.isAlive()){
runner.setPriority(Thread.MIN_PRIORITY);
runner.run();
}
//return null for now (until next time, whent the image will be in the cache!.)
return null;
}
}
最佳答案
runner.run();
那不是启动一个单独的线程,而只是在调用线程上执行run方法的内容。你可能想要
runner.start();
此外,您不能多次启动线程,所以
if(!runner.isAlive()){
这个检查可能不是很有用。当您需要图像时(或当您启动应用程序时)启动线程,然后等待它完成它的工作。如果您需要更复杂的逻辑,例如线程池或错误处理,您可能应该只使用用于异步图像加载的库。
关于java - Android 工作线程卡住主线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8033380/