Как повысить производительность (первое время загрузки, гладкость прокрутки) GridView, рендеринга многих больших изображений?

Мое приложение позволяет пользователям делать снимки с помощью своего приложения камеры, которое сохраняется в папке, предназначенной для приложения.

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

Снимок экрана диалога «Выбрать изображения для отправки»

К сожалению, диалог «выбирать изображения для отправки» занимает много времени, чтобы загружать изначально, и очень сильно «прерывистый» (частые заметные паузы) при прокрутке. Я подозреваю, что это связано с тем, что изображения очень большие – снимки, сделанные с моей камерой, составляют около 2,3 МБ. Первоначальный экран (15 изображений, отображаемых), таким образом, должен вытащить 34,5 МБ с диска, прежде чем он сможет отобразить.

GridView layout.xml

<!-- ... --> <GridView android:id="@+id/gvSelectImage" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:numColumns="3" android:gravity="center" /> <!-- ... --> 

Адаптер getView ()

 @Override public View getView(final int position, View convertView, ViewGroup parent) { File pic = pics[position]; View checkedImageView = LayoutInflater.from(context).inflate(R.layout.checked_image, parent, false); final ImageView imageView = (ImageView) checkedImageView.findViewById(R.id.checkableImage); /* LOAD IMAGE TO DISPLAY */ //imageView.setImageURI(pic.toURI())); // "exceeds VM budget" Bitmap image; try { int imageWidth = 100; image = getBitmapFromFile(pic, imageWidth); // TODO: slooow... } catch (IOException e) { throw new RuntimeException(e); } imageView.setImageBitmap(image); /* SET CHECKBOX STATE */ final CheckBox checkBoxView = (CheckBox) checkedImageView.findViewById(R.id.checkBox); checkBoxView.setChecked(isChecked[position]); /* ATTACH HANDLERS */ checkBoxView.setOnCheckedChangeListener(new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { CheckableLocalImageAdapter.this.isChecked[position] = checkBoxView.isChecked(); } }); imageView.setOnClickListener(new OnClickListener() { public void onClick(View v) { checkBoxView.setChecked(!checkBoxView.isChecked()); } }); return checkedImageView; } 

getBitmapFromFile() только что адаптирован из ответа, указанного на https://stackoverflow.com/a/823966/633626 . Я отмечаю, что код там дважды вызывает decodeStream() и может удваивать мой ввод-вывод, но я думаю, что диалог будет слишком медленным и слишком рывким, даже если я сокращу вдвое количество времени на рендеринг.

Мой тестовый телефон является стандартным Samsung Galaxy S II, если это актуально. Я подозреваю, что более старые устройства будут еще медленнее / choppier.

Какой лучший способ улучшить производительность здесь? Я предполагаю, что комбинация AsyncTask для загрузки каждого изображения (так что диалог может загружаться до отображения всех изображений) и какого-то кэширования (чтобы прокрутка не требовала рендеринга изображений и не была отрывистой), но я «Я потерял, как скомбинировать эти штуки с остальной частью моей головоломки.

Вместо этого вы захотите работать с эскизами . Загрузка всего изображения с SD-карты всегда будет медленной. Загружайте полную версию тех, которые они действительно хотят отправить.

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

Вот встроенный класс, который поможет вам их восстановить.

Попробуйте загрузить ваши изображения с помощью SampleSize в GridView:

 BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inSampleSize = 7; Bitmap bitmap = BitmapFactory.decodeFile(f.getPath(), opts); 

Подробнее о вариантах здесь

А также вы можете поменять загрузку изображения на Thread или AsyncTask.

Intereting Posts
Сделать ссылку в браузере Android запустите мое приложение? Есть ли простой способ сказать, является ли произвольная строка хорошо сформированной JSON в Android? Android. Как разместить позиции в смещении относительно центра / верхнего / нижнего (и т. Д.) Их родителя? Синхронизировать таблицу базы данных SQLite / Android с удаленной базой данных MySQL (через PHP) Android 'не распознается как внутренняя или внешняя команда SetColorFilter не работает Как связать layout_width и layout_height с использованием привязки данных в Android Должен ли MediaPlayer работать в отдельном потоке? Показывать всплывающее меню при нажатии элемента панели действий. Добавление нескольких маркеров в Google Maps API v2 Android Run-as Пакет «abc» неизвестен – Galaxy S4 Jellybean или Android 4.3 Gradle не может удалить каталог из-за .fuse_hidden HorizontalScrollView может содержать только один прямой дочерний объект Панель инструментов Appompat не отображается с помощью навигационного ящика Отправьте push на Android с помощью C # с помощью FCM (Firebase Cloud Messaging)