Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android工作线程冻结主线程_Java_Android_Multithreading_Android Layout - Fatal编程技术网

Java Android工作线程冻结主线程

Java Android工作线程冻结主线程,java,android,multithreading,android-layout,Java,Android,Multithreading,Android Layout,我正在开发一个应用程序,它实现了一个包含图像的自定义ListView。我能够让listview下载并缓存图像,但我想将下载转移到一个单独的线程上。为此,我创建了一个CachedLogoDownloader类,其目标是异步下载图像并将其保存在内存中,以便稍后由自定义适配器类访问 问题是线程占用了整个UI。即使run()中的代码只是一个“thread.sleep()”,只要出现对徽标图像的请求,UI就会停止。类似地,在run()中放置无限循环会导致程序无限期挂起 class CachedLogoDo

我正在开发一个应用程序,它实现了一个包含图像的自定义ListView。我能够让listview下载并缓存图像,但我想将下载转移到一个单独的线程上。为此,我创建了一个CachedLogoDownloader类,其目标是异步下载图像并将其保存在内存中,以便稍后由自定义适配器类访问

问题是线程占用了整个UI。即使run()中的代码只是一个“thread.sleep()”,只要出现对徽标图像的请求,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;
    }



}
class CachedLogoDownloader{
私有HashMap缓存=新建HashMap();
语境;
ArrayList FIDs;
螺纹流道;
公共CachedLogoDownloader(文本上下文){
this.context=inContext;
//要下载的公司徽标列表(通过FID)
FIDs=新的ArrayList();
//异步下载线程(用于低端设备的单线程。但是获取图像的速度应该不会太慢)
runner=新线程(新可运行(){
公开募捐{
用于(字符串FID:FIDs){
Log.d(Cloud.DEBUG_标记,图标可运行:“+FID”);
位图tempImage=Cloud.lookupIcon(上下文,FID);
cache.put(FID、tempImage);
FIDs.移除(FID);
}
}
});
}
公共标识(公司A公司){
字符串currentFID=aCompany.getFID();
//如果图像已经缓存,则返回缓存的图像
if(cache.containsKey(currentFID))
{
返回cache.get(currentFID);
}
其他的
{
//将徽标添加到要下载的徽标列表中
添加FIDs(当前FID);
//如果下载线程已完成(或尚未启动),请让它下载内容。
如果(!runner.isAlive()){
runner.setPriority(Thread.MIN_PRIORITY);
runner.run();
}
//现在返回空值(直到下一次,图像将在缓存中!)
返回null;
}
}
}

runner.run()

这不是启动单独的线程,而是在调用线程上执行run方法的内容。你可能想要

runner.start()

此外,不能多次启动线程,因此

如果(!runner.isAlive()){

此检查可能不是很有用。在需要映像时(或启动应用程序时)启动线程,然后等待它完成工作。如果需要更复杂的逻辑,如线程池或错误处理,则可能应该使用库来异步加载映像。

而不是runner.run()您应该使用runner.start(),否则您的thread run()方法实际上在同一个线程中执行。