Невозможно получить выигрыш в производительности от ThreadPoolExecutor - PullRequest
0 голосов
/ 09 октября 2018

Я загружаю довольно много изображений, используя ThreadPoolExecutor.Производительность приложения для Android превосходна при соединении со скоростью 10 Мбит / с и обычно превышает результаты аналогичной загрузки данных на iPad.

Однако, когда я запускаю то же приложение при более быстром подключении к Интернету (60 Мбит / с), приложение для Android не можетдля синхронизации быстрее (занимает 6 минут), в то время как iPad загружает все за минуту.

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

У меня Samsung Galaxy Tab S2 (T173) с окта-ядроми 3 ГБ ОЗУ и iPad Air.

Это связано с ограничениями процессора на платформе Android или я что-то упустил в конце разработки, пожалуйста, помогите ... заранее спасибо.

ЭтоВот как я использую ThreadPoolExecutor.

int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
executor = new ThreadPoolExecutor(
               NUMBER_OF_CORES * 2,
               NUMBER_OF_CORES * 2,
               60L,
               TimeUnit.SECONDS,
               new LinkedBlockingQueue<Runnable>()
          );
 executor.allowCoreThreadTimeOut(true);

 for (int i = 0; i < totalCount; i++) {
                 executor.execute(new ImageDownloader(context, i, new Handler(), imageUrl, diagram_names.get(i), null));
            }

А вот класс ImageDownloader:

public class ImageDownloader implements Runnable {
int threadNo;
Handler handler;
String imageUrl;
public static final String TAG = "Image Downloader";
String imageName, calledFrom;
Activity applicationContext;
public ImageDownloader() {

}

public ImageDownloader(Activity applicationContext, int threadNo, Handler handler, String imageUrl, String imageName, String calledFrom) {
    this.applicationContext = applicationContext;
    this.threadNo = threadNo;
    this.handler = handler;
    this.imageUrl = imageUrl;
    this.imageName = imageName;
    this.calledFrom = calledFrom;
}

@Override
public void run() {
        if(CommonMethods.isNetworkAvailable(applicationContext))
            getBitmap(imageUrl, imageName);
}

private Bitmap getBitmap(String url, String imageName) {
    Bitmap bitmap = null;
    try {
        saveImage(Picasso.with(applicationContext).load(url).get(), imageName, url);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return bitmap;
}

private void saveImage(Bitmap bmImg, String name) {
    if (bmImg != null) {
        try {
            File myDir = new File(Environment.getExternalStorageDirectory()
                    .toString() + "/AppReader/saved_signature");

            // make the directory if it does not exist yet
            if (!myDir.exists()) {
                myDir.mkdirs();
            }

            try {
                FileOutputStream out = new FileOutputStream(file);
                Log.i("in save()", "after outputstream");
                DisplayMetrics displayMetrics = applicationContext.getResources().getDisplayMetrics();
                int width = displayMetrics.widthPixels;
                int height = displayMetrics.heightPixels;
                Bitmap resizedBitmap = bmImg;
                resizedBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
                out.flush();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

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

1 Ответ

0 голосов
/ 10 октября 2018

Я предлагаю вам сделать некоторые оптимизации - например, используйте, например, java.util.concurrent.Executors.newCachedThreadPool () - это опять-таки ThreadPoolExecutor, но настроен по-другому - см. Doc https://developer.android.com/reference/java/util/concurrent/Executors.html#newCachedThreadPool() для получения дополнительной информации

Также в приведенном выше коде кажется, что вы пытаетесь записывать всегда в один и тот же файл (аргумент name не используется в saveImage), что определенно не нормально, потому что его блокировка, но я думаю, что это просто ошибка копирования / вставки.

И также не повредит, если вы переместите код "init" - проверки на наличие каталога, displayMetrics и т. Д. В другие части кода, поэтому они не выполняются в каждом потоке.

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

...