Ускорить выполнение кэширования изображения в Android

#java #android #image-processing #bitmap

#java #Android #обработка изображений #растровое изображение

Вопрос:

У меня есть следующий код для сохранения изображения в каталоге кэша моего приложения. Метод вызывается в отдельном Runnable() , который, как я надеялся, ускорит работу приложения. В нынешнем виде сжатие растрового изображения очень дорого для процессора и приводит к тому, что остальная часть приложения работает очень медленно. Как я могу ускорить это?

 public void combineImages(Bitmap bmp, int count, int count2){                   
        Bitmap bottomImage = bmp.copy(Config.RGB_565, true);
        float width = bmp.getWidth();
        float height = bmp.getHeight(); 
        bmp.recycle();  

        Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image1);
        Bitmap topImage = myBitmap.copy(Config.ARGB_4444, true);
        myBitmap.recycle();
        myBitmap = null;

        Canvas comboImage = new Canvas(bottomImage);
        // Then draw the second on top of that
        comboImage.drawBitmap(topImage, (width / 2) - 200, (height / 2) - 160, null);

        topImage.recycle(); 
        topImage = null;

        // bottomImage is now a composite of the two.

        // To write the file out to the Cache:
        OutputStream os = null;
        try {
            os = new FileOutputStream(getApplicationContext().getCacheDir()   "/"   path);
            bottomImage.compress(CompressFormat.PNG, 50, os); //Here it is most expensive and what slows the app down

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  

Комментарии:

1. в какой поток вы отправляете Runnable ?

2. @techiServices: Оно отправляется в другой исполняемый экземпляр, который, в свою очередь, запускается в главном потоке пользовательского интерфейса.

Ответ №1:

Вы должны использовать отдельный поток для запуска метода, либо создав новый внутренний класс, который расширяет Thread и вызывает метод, либо создав новый Thread и передав Runnable в качестве аргумента конструктора. Если это текущая задача, то есть вам нужно обработать много растровых изображений, вы можете захотеть взглянуть на HandlerThread или IntentService .

Комментарии:

1. У меня это уже есть, у меня есть поток пользовательского интерфейса, в котором я создаю объект Thread, который вызывает метод SaveImage() в его методе Runnable(), внутри этого метода есть другой объект Thread, а в методе Runnable() вызывается приведенный выше код. Я вообще не думаю, что это проблема с потоками, приложение работает очень быстро, когда не используется метод сжатия для растрового объекта.

2. @SamRowley: извините, я неправильно понял, из вашего комментария выяснилось, что вы запускали этот метод в потоке пользовательского интерфейса. Вы тестируете на физическом устройстве или эмуляторе? Глядя на исходный код Android, метод compress вызывает встроенную функцию.

3. Я запускаю его на 2 разных устройствах (HTC Desire и Samsung Nexus S), он ускорился, изменив формат сжатия на JPEG, а не PNG на Nexus, но на Desire он по-прежнему работает очень медленно.

4. @techiServices — Да, у меня есть, я использовал setDaemon (true); для потоков, которые я хочу, прямо в фоновом режиме. Я предполагаю, что это аппаратная проблема, которая медленно работает на HTC, она очень хорошо работает на Nexus S.

5. @SamRowley: я бы предположил то же самое, поскольку метод compress запускает встроенную функцию c, однако приоритет, о котором я говорю, устанавливается с помощью Thread.setPriority метода или конструктора, например, с помощью Thread.MIN_PRIORITY .