Android Looper.prepare () и AsyncTask - PullRequest
       6

Android Looper.prepare () и AsyncTask

2 голосов
/ 09 февраля 2012

Привет, у меня есть несколько вопросов, касающихся Looper.prepare () и AsyncTasks.

В моем приложении у меня есть AsyncTask, которая запускает другие AsyncTask. У меня было 2 AsyncTasks Search и GetImage. Задача GetImage выполняется несколько раз в задаче поиска. Работает нормально.

Однако недавно я реализовал кэширование изображений, как описано здесь: http://android -developers.blogspot.com / 2010/07 / многопоточность-для-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 для загрузки изображения. Он также содержит обработчик и 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 Ответ

6 голосов
/ 09 февраля 2012

Что действительно происходит, так это то, что вы пытаетесь выполнить что-то в фоновом потоке, для которого требуется выполнение потока пользовательского интерфейса.

Looper - это часть системы, которая гарантирует, что транзакции выполняются по порядку, и устройство отвечает, как и должно.

95% времени, когда вы получаете ошибку Looper, это действительно означает, что вам нужно переместить часть вашего кода в поток пользовательского интерфейса, в Asynctask это означает перемещение либо в onPostExecute, либо onProgressUpdate. 1007 *

В вашем случае это выглядит так, как будто вы добавляете представления, которые являются частью пользовательского интерфейса и, следовательно, могут вызвать проблемы. Если это на самом деле не является причиной проблемы, проверка трассировки стека должна дать вам некоторые подсказки.

В качестве примечания: если вы ДОЛЖНЫ позвонить Looper.prepare(), я бы назвал это в начале вашей ветки. Однако, как правило, это рекомендуется, чтобы избежать необходимости вызывать его.

...