Android Looper.prepare()和AsyncTask

时间:2012-02-09 18:45:22

标签: android multithreading android-asynctask handler

您好我对Looper.prepare()和AsyncTasks有一些疑问。

在我的应用程序中,我有一个启动其他AsyncTasks的AsyncTask。我有2个AsyncTasks搜索和GetImage。 GetImage任务在搜索任务中执行多次。它工作正常。

但是最近我实现了图像缓存,如下所述: http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html

实施此操作后,我开始出现间歇性崩溃

02-09 17:40:43.334:W / System.err(25652):java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序

我不确定应该在哪里调用prepare()。这是代码的粗略轮廓

Search extends AsyncTask{

    @Override
    protected void doInBackground(){
        ArrayList<Object> objs = getDataFromServer();
        ArrayList<View> views = new ArrayList<View>();
        for(Object o: objs){
            //multiple AsyncTasks may be started while creating views
            views.add(createView(o));
        }
        for(View v: views){
            publishProgess(v);
        }
   }
}

public View createView(Object o){

    //create a view
    ImageView iv = .....;
    ImageDownloader.getInstance().download(url,iv);
}

ImageDownloader可以在上面的链接中看到,它是另一个下载图像的AsyncTask。它还包含一个Handler和Runnable,用于清除每次下载时重置的缓存。我确实对ImageDownloader做了一次更改,我把它变成了单身。

 public static ImageDownloader getInstance(){
    if(instance == null){
        //tried adding it here but it results in occasional
        //cannot create more than one looper per thread error
        Looper.prepare();
        instance= new ImageDownloader();
    }
    return instance;
}

ImageDownloader下载方法可能被称为10次,这为每个下载创建了一个AysncTask。所以过去几天我一直在摸不着头脑,希望你们能帮忙。

1 个答案:

答案 0 :(得分:6)

实际上你正在尝试在需要UI线程运行的后台线程上执行某些操作。

Looper是系统的一部分,可确保按顺序完成事务,并且设备正在响应。

95%的情况下,当你收到Looper错误时,它真正意味着你需要将部分代码移动到UI线程,在Asynctask中这意味着将它移动到onPostExecute或{{1 }}

在您的情况下,您似乎正在添加视图,这是UI的一部分,因此会导致问题。如果这实际上不是造成问题的原因,那么对堆栈跟踪的检查应该会给你一些线索。

作为旁注,如果你必须打电话给onProgressUpdate我会在你的主题的开头叫它。但是,通常建议不要调用它。