Ну, через 2 дня я борюсь, пожалуйста, помогите мне решить эту проблему.Загрузка изображений с SDK в gridview, выбрасывание исключения из памяти?
Я хочу загрузить список всех изображений во внешнем хранилище в мое gridview.
Мне удалось получить список изображений из системы, используя этот метод.
public static ArrayList<String> getFilePaths(Activity context)
{
Uri u = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.Images.ImageColumns.DATA};
Cursor c = null;
SortedSet<String> dirList = new TreeSet<String>();
ArrayList<String> resultIAV = new ArrayList<String>();
String[] directories = null;
if (u != null)
{
c = context.managedQuery(u, projection, null, null, null);
}
if ((c != null) && (c.moveToFirst()))
{
do
{
String tempDir = c.getString(0);
tempDir = tempDir.substring(0, tempDir.lastIndexOf("/"));
try{
dirList.add(tempDir);
}
catch(Exception e)
{
}
}
while (c.moveToNext());
directories = new String[dirList.size()];
dirList.toArray(directories);
}
for(int i=0;i<dirList.size();i++)
{
File imageDir = new File(directories[i]);
File[] imageList = imageDir.listFiles();
if(imageList == null)
continue;
for (File imagePath : imageList) {
try {
if(imagePath.isDirectory())
{
imageList = imagePath.listFiles();
}
if (imagePath.getName().contains(".jpg")|| imagePath.getName().contains(".JPG")
|| imagePath.getName().contains(".jpeg")|| imagePath.getName().contains(".JPEG")
|| imagePath.getName().contains(".png") || imagePath.getName().contains(".PNG")
|| imagePath.getName().contains(".gif") || imagePath.getName().contains(".GIF")
|| imagePath.getName().contains(".bmp") || imagePath.getName().contains(".BMP")
)
{
String path= imagePath.getAbsolutePath();
resultIAV.add(path);
}
}
// }
catch (Exception e) {
e.printStackTrace();
}
}
}
return resultIAV;
}
Теперь хитрая часть приходит, я знаю, что я не могу загрузить фактические изображения, как это съедает много памяти, и в конечном итоге получить bitmap Outofmemory exception
поэтому у меня есть загрузчик изображений с исполнителем, который выполняет загрузку изображений в отдельном поток и загрузочное изображение асинхронно здесь - загрузчик изображений.
public class AbstractImageLoader {
private static ExecutorService executorService;
private static AbstractImageLoader loader;
public static int maxWidth;
Handler handler;;
private Map<ImageView,String> imageViews;
static {
AbstractImageLoader.executorService = Executors.newFixedThreadPool(5);
}
public AbstractImageLoader(final Context context) {
this.imageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
this.handler = new Handler();
AbstractImageLoader.maxWidth = context.getResources().getDisplayMetrics().widthPixels/3;
}
public static AbstractImageLoader getInstance(final Context context) {
if (AbstractImageLoader.loader == null) {
AbstractImageLoader.loader = new AbstractImageLoader(context);
}
return AbstractImageLoader.loader;
}
private void queuePhoto(final String s, final ImageView imageView, final int n) {
AbstractImageLoader.executorService.submit(new PhotosLoader(new PhotoToLoad(s, imageView, n)));
}
public void DisplayImage(final String s, final ImageView imageView) {
this.DisplayImage(s, imageView, -1);
}
public void DisplayImage(final String s, final ImageView imageView, final int imageResource) {
this.imageViews.put(imageView, s);
final Bitmap value = MemCache.get(s);
if (value != null) {
imageView.setImageBitmap(value);
return;
}
this.queuePhoto(s, imageView, imageResource);
if (imageResource > -1) {
imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageView.setImageResource(imageResource);
return;
}
imageView.setImageDrawable((Drawable)null);
}
public void DisplayImage(final String s, final ImageView imageView, final Drawable imageDrawable) {
this.imageViews.put(imageView, s);
final Bitmap value = MemCache.get(s);
if (value != null) {
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setImageBitmap(value);
}
else {
this.queuePhoto(s, imageView, -1);
if (imageDrawable != null) {
imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageView.setImageDrawable(imageDrawable);
}
}
}
public void clearCache() {
MemCache.clear();
}
public void delete(final String s) {
MemCache.remove(s);
}
protected Bitmap getBitmap(final String ex) {
final Bitmap bitmap = null;
final File file = new File((String)ex);
if (!file.exists()) {
final String[] list = file.getParentFile().list(new FileUtils$Filters$6());
Object o = bitmap;
if (list != null) {
if (list.length != 0) {
o = new File(file.getParent(), list[0]);
final String absolutePath = ((File)o).getAbsolutePath();
o = ThumbUtils.getThumbnail(absolutePath, AlbumViewLoader.maxWidth);
return ThumbUtils.getThumbnail((String)ex, AlbumViewLoader.maxWidth);
}
o = bitmap;
}
return (Bitmap)o;
}
return ThumbUtils.getThumbnail((String)ex, AlbumViewLoader.maxWidth);
}
boolean imageViewReused(final PhotoToLoad photoToLoad) {
final String s = imageViews.get(photoToLoad.imageView);
return s == null || !s.equals(photoToLoad.url);
}
class BitmapDisplayer implements Runnable
{
Bitmap bitmap;
PhotoToLoad photoToLoad;
public BitmapDisplayer(final Bitmap bitmap, final PhotoToLoad photoToLoad) {
this.bitmap = bitmap;
this.photoToLoad = photoToLoad;
}
@Override
public void run() {
if (!AbstractImageLoader.this.imageViewReused(this.photoToLoad)) {
if (this.bitmap != null) {
this.photoToLoad.imageView.setImageBitmap(this.bitmap);
this.photoToLoad.imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
return;
}
if (this.photoToLoad.placeholder_stub > -1) {
this.photoToLoad.imageView.setImageResource(this.photoToLoad.placeholder_stub);
this.photoToLoad.imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
}
}
}
}
private class PhotoToLoad
{
public ImageView imageView;
public int placeholder_stub;
public String url;
public PhotoToLoad(final String url, final ImageView imageView, final int placeholder_stub) {
this.url = url;
this.imageView = imageView;
this.placeholder_stub = placeholder_stub;
}
}
class PhotosLoader implements Runnable
{
PhotoToLoad photoToLoad;
PhotosLoader(final PhotoToLoad photoToLoad) {
this.photoToLoad = photoToLoad;
}
@Override
public void run() {
try {
/* if (!imageViewReused(this.photoToLoad)) {
return;
}*/
final Bitmap bitmap = AbstractImageLoader.this.getBitmap(this.photoToLoad.url);
if (bitmap != null) {
MemCache.put(this.photoToLoad.url, bitmap);
}
AbstractImageLoader.this.handler.post((Runnable)new BitmapDisplayer(bitmap, this.photoToLoad));
}
catch (Throwable t) {
t.printStackTrace();
}
}
}
}
вот мой служебный класс, который создает растровое:
public static Bitmap getThumbnail(final String s, int n) {
final BitmapFactory.Options bitmapFactory$Options = new BitmapFactory.Options();
bitmapFactory$Options.inSampleSize = 1;
bitmapFactory$Options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(s, bitmapFactory$Options);
if (bitmapFactory$Options.mCancel || bitmapFactory$Options.outWidth == -1 || bitmapFactory$Options.outHeight == -1) {
return null;
}
final int outHeight = bitmapFactory$Options.outHeight;
final int outWidth = bitmapFactory$Options.outWidth;
final float max = Math.max(n/outWidth, n/outHeight);
n = (int)(outWidth * max);
final int n2 = (int)(outHeight * max);
bitmapFactory$Options.inSampleSize = calculateInSampleSize(bitmapFactory$Options, n, n);
bitmapFactory$Options.inJustDecodeBounds = false;
bitmapFactory$Options.inDither = true;
bitmapFactory$Options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bmp = BitmapFactory.decodeFile(s, bitmapFactory$Options);
return ThumbnailUtils.extractThumbnail(bmp, n, n, 2);
}
Так вот мои вопросы:
1.In мой эскиз метод утилита этот расчет:
final float max = Math.max(n/outWidth, n/outHeight);
n = (int)(outWidth * max);
final int n2 = (int)(outHeight * max);
n всегда возвращается как 0. Следовательно, эскиз не загружается, поэтому на время я жестко запрограммировал его на 212 и загрузка миниатюр начала
Но после загрузки определенного количества изображений я все еще получаю out of memory exception
вот LogCat:
java.lang.OutOfMemoryError: Failed to allocate a 347790 byte allocation with 294944 free bytes and 288KB until OOM
05-10 09:57:19.448 22498-22683/com.geekmk.audiofx W/System.err: at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
05-10 09:57:19.448 22498-22683/com.geekmk.audiofx W/System.err: at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
05-10 09:57:19.448 22498-22683/com.geekmk.audiofx W/System.err: at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:639)
05-10 09:57:19.448 22498-22683/com.geekmk.audiofx W/System.err: at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:615)
05-10 09:57:19.448 22498-22683/com.geekmk.audiofx W/System.err: at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:391)
05-10 09:57:19.448 22498-22683/com.geekmk.audiofx W/System.err: at com.geekmk.audiofx.test.ThumbUtils.getThumbnail(ThumbUtils.java:66)
05-10 09:57:19.448 22498-22683/com.geekmk.audiofx W/System.err: at com.geekmk.audiofx.test.AbstractImageLoader.getBitmap(AbstractImageLoader.java:110)
05-10 09:57:19.448 22498-22683/com.geekmk.audiofx W/System.err: at com.geekmk.audiofx.test.AbstractImageLoader$PhotosLoader.run(AbstractImageLoader.java:171)
05-10 09:57:19.448 22498-22683/com.geekmk.audiofx W/System.err: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
05-10 09:57:19.448 22498-22683/com.geekmk.audiofx W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
05-10 09:57:19.448 22498-22683/com.geekmk.audiofx W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
05-10 09:57:19.448 22498-22683/com.geekmk.audiofx W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
05-10 09:57:19.448 22498-22683/com.geekmk.audiofx W/System.err: at java.lang.Thread.run(Thread.java:818)
Пожалуйста, помогите мне Спасибо заранее.
Вы действительно почти из кучи пространства. Загрузите меньше изображений. Перерабатывайте объекты «Bitmap», где вы можете (см. 'InBitmap' из' BitmapFactory.Options'). Разрешить объекты «Bitmap» собирать мусор, когда они больше не нужны и не могут быть переработаны. – CommonsWare
Восстановить объекты Bitmap? Можете ли вы дать ссылку на ссылку или объяснить, как ее решить? – Manikanta
http://developer.android.com/training/displaying-bitmaps/manage-memory.html http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inBitmap – CommonsWare