Intereting Posts
Могу ли я запустить Android Studio (эмулятор Android SDK) на виртуальной машине Microsoft-Hyper-V? Есть ли способ динамически изменить значок приложения Android, например, приложение «Календарь»? Как получить скорость в Android-приложении с помощью Location или акселерометра или каким-либо другим способом Передача данных с USB (плодовитый) на устройство Android Обновить MusicPlayer SeekBar в сервисе Android / Java: длинный получает отрицательный, не превышая max_value Почему я получаю NoClassDefFoundError при выполнении моего теста в ActionBarActivity? Android Studio и Kotlin: нерешенные ссылки: также Как показать дерево зависимостей в Android Studio? Как использовать Master / Detail Flow вместе с вкладками на Android SwipeRefreshLayout вмешивается в setOnScrollListener Подобно Google Play Можно ли программным образом удалить запоминаемые группы Wifi Direct из Android? Android рисовать собственный указатель большого пальца в XML Как установить максимальную дату в диалоговом окне datepicker в android?

Управление несколькими асинтесами для загрузки нескольких изображений из html-кода, утечки памяти, любых идей?

Я разрабатываю приложение для Android. Теперь я разбираю bbcode в html и отображаю его внутри textview, textview находится внутри пользовательского списка. Я использую Html.ImageGetter () для отображения изображений, загруженных из AsyncTask.

Он отлично работает для небольшого количества фотографий. Но если приложение попросит загрузить 40-50 фотографий, создаются 40-50 задач, и это становится беспорядком. Каждая задача открывает поток для загрузки изображений. После этого он декодирует байты в растровые изображения, изменяет их размер, сохраняет их на SD-карте и перерабатывает растровые изображения.

Теперь, если приложение загружает все эти изображения одновременно, оно использует огромное количество бара. Мне удалось пропустить 48 мб. Существует большой разрыв между 16 и 48 🙁 Я искал, как это решить. Я загрузил код AsyncTask из google:

http://google.com/codesearch/p?hl=en&sa=N&cd=2&ct=rc#uX1GffpyOZk/core/java/android/os/AsyncTask.java&q=lang:java%20AsyncTask

И установите размер пула на 3. Но это не помогло. Я действительно не могу понять, где я теряю барана. Как только я поставил большую очередь задач, мой баран сходит с ума. После получения нескольких изображений это становится хуже. Я не думаю, что это изображения, так как я могу добраться до 30 мб до отображения любого изображения. Само приложение, включая представление, информацию и его сервис, использует 13 мб, все остальные просочились здесь.

Сама ли очередь делает большие распределения бара? Или Html.ImageGetter () как-то утечка огромного объема памяти? Есть лучший способ сделать это?

Здесь я загружаю изображения:

public void LoadImages(String source) { myurl = null; try { myurl = new URL(source); } catch (MalformedURLException e) { e.printStackTrace(); } new DownloadImageFromPost().execute(myurl); } private class DownloadImageFromPost extends AsyncTask<URL, Integer, Bitmap> { @Override protected Bitmap doInBackground(URL... params) { URL url; Log.d(TAG, "Starting new image download"); try { url = params[0]; HttpURLConnection connection = (HttpURLConnection) url .openConnection(); int length = connection.getContentLength(); InputStream is = (InputStream) url.getContent(); byte[] imageData = new byte[length]; int buffersize = (int) Math.ceil(length / (double) 100); int downloaded = 0; int read; while (downloaded < length) { if (length < buffersize) { read = is.read(imageData, downloaded, length); } else if ((length - downloaded) <= buffersize) { read = is.read(imageData, downloaded, length - downloaded); } else { read = is.read(imageData, downloaded, buffersize); } downloaded += read; publishProgress((downloaded * 100) / length); } Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0, length); if (bitmap != null) { Log.i(TAG, "Bitmap created"); } else { Log.i(TAG, "Bitmap not created"); } is.close(); return bitmap; } catch (MalformedURLException e) { Log.e(TAG, "Malformed exception: " + e.toString()); } catch (IOException e) { Log.e(TAG, "IOException: " + e.toString()); } catch (Exception e) { } return null; } protected void onPostExecute(Bitmap result) { String name = Environment.getExternalStorageDirectory() + "/tempthumbs/" + myurl.toString().hashCode() +".jpg"; String rname = Environment.getExternalStorageDirectory() + "/tempthumbs/" + myurl.toString().hashCode() +"-t.jpg"; try { if (result != null) { hasExternalStoragePublicPicture(name); ImageManager manager = new ImageManager(context); Bitmap rezised = manager.resizeBitmap(result, 300, 300); saveToSDCard(result, name, myurl.toString().hashCode() +".jpg"); saveToSDCard(rezised, rname, myurl.toString().hashCode() +"-t.jpg"); result.recycle(); rezised.recycle(); } else { } } catch(NullPointerException e) { } Log.d(TAG, "Sending images loaded announcement"); Intent i = new Intent(IMAGE_LOADED); i.putExtra("image", name); i.putExtra("source", myurl.toString()); i.putExtra("class", true); context.sendBroadcast(i); } } private boolean hasExternalStoragePublicPicture(String name) { File file = new File(name); if (file != null) { file.delete(); } try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } return file.exists(); } public void saveToSDCard(Bitmap bitmap, String name, String nam) { boolean mExternalStorageAvailable = false; boolean mExternalStorageWriteable = false; String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { mExternalStorageAvailable = mExternalStorageWriteable = true; Log.v(TAG, "SD Card is available for read and write " + mExternalStorageAvailable + mExternalStorageWriteable); saveFile(bitmap, name, nam); } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { mExternalStorageAvailable = true; mExternalStorageWriteable = false; Log.v(TAG, "SD Card is available for read " + mExternalStorageAvailable); } else { mExternalStorageAvailable = mExternalStorageWriteable = false; Log.v(TAG, "Please insert a SD Card to save your Video " + mExternalStorageAvailable + mExternalStorageWriteable); } } private void saveFile(Bitmap bitmap, String fullname, String nam) { ContentValues values = new ContentValues(); File outputFile = new File(fullname); values.put(MediaStore.MediaColumns.DATA, outputFile.toString()); values.put(MediaStore.MediaColumns.TITLE, nam); values.put(MediaStore.MediaColumns.DATE_ADDED, System .currentTimeMillis()); values.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg"); Uri uri = context.getContentResolver().insert( android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);; try { OutputStream outStream = context.getContentResolver() .openOutputStream(uri); bitmap.compress(Bitmap.CompressFormat.JPEG, 95, outStream); outStream.flush(); outStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } bitmap.recycle(); } 

И здесь я называю Html.ImageGetter (), это внутри списка getView:

 holder.content.setText(Html.fromHtml( processor.preparePostText(posts.get(position).post_content), new Html.ImageGetter() { @Override public Drawable getDrawable(String source) { Log.d("Forum Service", "image source: " + source); if (imageSources.contains(source)) { for (int x = 0; x < imageSources.size(); x++) { if (source.equals(imageSources.get(x))) { String tmp = oImages.get(x); tmp = tmp.substring(0, tmp.length() - 4); tmp = tmp + "-t.jpg"; Drawable d = Drawable.createFromPath(tmp); try { d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); } catch (NullPointerException e) { } Log.d("Forum Service", "Loaded image froms sdcard"); return d; } } } else if (notLoadedImages.contains(source)) { Log.d("Forum Service", "Waiting for image"); return null; } else { notLoadedImages.add(source); LoadAllIcons loader = new LoadAllIcons(context); loader.LoadImages(source); Log.d("Forum Service", "Asked for image"); return null; } return null; } }, null)); 

Благодаря!

Наконец, проблема заключалась в том, что все задачи загружались одновременно. Для этого 40 изображений, которые выделяются во время загрузки. Мне удалось ограничить количество выполняемых задач, выполнив эти изменения в AsyncTask:

 private static final int CORE_POOL_SIZE = 2; private static final int MAXIMUM_POOL_SIZE = 2; private static final int KEEP_ALIVE = 1; private static final BlockingQueue<Runnable> sWorkQueue = new LinkedBlockingQueue<Runnable>(100); 

Solutions Collecting From Web of "Управление несколькими асинтесами для загрузки нескольких изображений из html-кода, утечки памяти, любых идей?"