Тема Android Worker зависает Основная тема - PullRequest
1 голос
/ 07 ноября 2011

Я работаю над приложением, которое реализует пользовательский ListView, содержащий изображения.Мне удалось получить просмотр списка для загрузки и кэширования изображений, но я бы хотел перенести загрузку в отдельный поток.Для этого я создал класс CachedLogoDownloader , целью которого является асинхронная загрузка изображений и сохранение их в памяти для последующего доступа к этому классу адаптера.

Проблема в том, что поток поддерживает весь пользовательский интерфейс.Даже когда код в run () был просто «thread.sleep ()», пользовательский интерфейс останавливался всякий раз, когда происходил запрос изображения логотипа.Аналогично, размещение бесконечного цикла в 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;
    }



}

}

1 Ответ

2 голосов
/ 07 ноября 2011

runner.run ();

Это не запуск отдельного потока, а просто выполнение содержимого метода run в вызывающем потоке.Вы, вероятно, хотите

runner.start ();

Кроме того, вы не можете запустить поток более одного раза, поэтому

if (! runner.isAlive ()) {

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...