Android 尽管减小了图像大小,但内存不足错误

Android 尽管减小了图像大小,但内存不足错误,android,android-asynctask,out-of-memory,decode,bitmapfactory,Android,Android Asynctask,Out Of Memory,Decode,Bitmapfactory,此应用程序运行正常,但速度太慢。它在一个UI线程上运行一切,当一个页面在gridView中加载了许多图像时,页面在加载之前需要很长的延迟。我使用android文档中名为“”的代码修复了此问题 使用现在加载的代码,gridview页面变化很快,您可以看到它在单独的背景线程中逐个加载每个小位图图像 在这段将AsyncTask用于多线程部分的代码中,它还使用了两种方法来减小映像大小以消除内存不足错误。我在这个程序的前一个单线程版本中使用了相同的图像缩减方法。无论图像有多大,它都不应大于图像还原方法设置

此应用程序运行正常,但速度太慢。它在一个UI线程上运行一切,当一个页面在gridView中加载了许多图像时,页面在加载之前需要很长的延迟。我使用android文档中名为“”的代码修复了此问题

使用现在加载的代码,gridview页面变化很快,您可以看到它在单独的背景线程中逐个加载每个小位图图像

在这段将AsyncTask用于多线程部分的代码中,它还使用了两种方法来减小映像大小以消除内存不足错误。我在这个程序的前一个单线程版本中使用了相同的图像缩减方法。无论图像有多大,它都不应大于图像还原方法设置的200dp乘以200dp。它在没有多线程的应用程序的旧版本中工作,并且在应用程序的新版本中大部分看起来都正常。但有一个奇怪的问题

我现在发现与BitmapFactory解码方法连接的内存不足错误

如何做到这一点是我开始测试应用程序与许多较小的图像,并把其中一个巨大的约10000 X 10000像素的位图。这应该不会造成问题,因为使用位图工厂选项将减少图像

这些错误不会马上发生。该应用程序可以正常工作一段时间,但在活动之间来回移动之后。3到5分钟后,它将崩溃

还有其他人有这样的问题吗?你能提供一些可能是我想了解的原因的想法吗?或者帮我开始寻找正确的方向

图像缩小代码如下所示,下面是logcat输出

    class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
    private final WeakReference<ImageView> imageViewReference;
    private String data = "";

    public BitmapWorkerTask(ImageView imageView) {
        // Use a WeakReference to ensure the ImageView can be garbage collected
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

    // Decode image in background.
    @Override
    protected Bitmap doInBackground(String... params) {
        data = params[0];
       // return imageProcessor(data);
        return decodeSampledBitmapFromResource(data, 100, 100);
    }

    // Once complete, see if ImageView is still around and set bitmap.
    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (imageViewReference != null && bitmap != null) {
            final ImageView imageView = imageViewReference.get();
            if (imageView != null) {
                imageView.setImageBitmap(bitmap);
            }
        }
    }
  }// end BitmapWorkerTask extends AsyncTask class

      public static Bitmap decodeSampledBitmapFromResource(String fileName, int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(fileName, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;

    return BitmapFactory.decodeFile(fileName, options);


}//end decodeSampledBitmapfromresource method


public static int calculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;

if (height > reqHeight || width > reqWidth) {
    if (width > height) {
        inSampleSize = Math.round((float)height / (float)reqHeight);
    } else {
        inSampleSize = Math.round((float)width / (float)reqWidth);
    }
}
return inSampleSize;
}// end calculateInSampleSize method
类BitmapWorkerTask扩展了AsyncTask{
私有最终WeakReference imageViewReference;
私有字符串数据=”;
公共位图工作任务(ImageView ImageView){
//使用WeakReference确保可以对ImageView进行垃圾收集
imageViewReference=新的WeakReference(imageView);
}
//在背景中解码图像。
@凌驾
受保护位图doInBackground(字符串…参数){
数据=参数[0];
//返回图像处理器(数据);
返回decodeSampledBitmapFromResource(数据,100100);
}
//完成后,查看ImageView是否仍然存在并设置位图。
@凌驾
受保护的void onPostExecute(位图){
if(imageViewReference!=null&&bitmap!=null){
最终ImageView=imageViewReference.get();
如果(imageView!=null){
设置图像位图(位图);
}
}
}
}//结束BitmapWorkerTask扩展异步任务类
公共静态位图decodeSampledBitmapFromResource(字符串文件名、int-reqWidth、int-reqHeight){
//使用INJUSTDECBOUNDS首次解码=true检查尺寸
final BitmapFactory.Options=new BitmapFactory.Options();
options.inJustDecodeBounds=true;
BitmapFactory.decodeFile(文件名、选项);
//计算样本大小
options.inSampleSize=计算样本大小(options、reqWidth、reqHeight);
//使用inSampleSize集合解码位图
options.inJustDecodeBounds=false;
返回BitmapFactory.decodeFile(文件名、选项);
}//end decodeSampledBitmapfromresource方法
公共静态整数计算示例大小(
BitmapFactory.Options选项、int reqWidth、int reqHeight){
//图像的原始高度和宽度
最终内部高度=options.outHeight;
最终整数宽度=options.outWidth;
int inSampleSize=1;
如果(高度>要求高度| |宽度>要求宽度){
如果(宽度>高度){
inSampleSize=数学圆((浮动)高度/(浮动)要求高度);
}否则{
inSampleSize=数学圆((浮动)宽度/(浮动)宽度);
}
}
返回样本大小;
}//结束计算样本大小方法

Logcat

17:52:28.340: E/AndroidRuntime(7812): FATAL EXCEPTION: main
17:52:28.340: E/AndroidRuntime(7812): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.v.splitter/com.v.splitter.AudioViewer}: android.view.InflateException: Binary XML file line #63: Error inflating class <unknown>
17:52:28.340: E/AndroidRuntime(7812): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
17:52:28.340: E/AndroidRuntime(7812): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
17:52:28.340: E/AndroidRuntime(7812): at android.app.ActivityThread.access$600(ActivityThread.java:123)
17:52:28.340: E/AndroidRuntime(7812): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
17:52:28.340: E/AndroidRuntime(7812): at android.os.Handler.dispatchMessage(Handler.java:99)
17:52:28.340: E/AndroidRuntime(7812): at android.os.Looper.loop(Looper.java:137)
17:52:28.340: E/AndroidRuntime(7812): at android.app.ActivityThread.main(ActivityThread.java:4424)
17:52:28.340: E/AndroidRuntime(7812): at java.lang.reflect.Method.invokeNative(Native Method)
17:52:28.340: E/AndroidRuntime(7812): at java.lang.reflect.Method.invoke(Method.java:511)
17:52:28.340: E/AndroidRuntime(7812): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
17:52:28.340: E/AndroidRuntime(7812): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
17:52:28.340: E/AndroidRuntime(7812): at dalvik.system.NativeStart.main(Native Method)
17:52:28.340: E/AndroidRuntime(7812): Caused by: android.view.InflateException: Binary XML file line #63: Error inflating class <unknown>
17:52:28.340: E/AndroidRuntime(7812): at android.view.LayoutInflater.createView(LayoutInflater.java:606)
17:52:28.340: E/AndroidRuntime(7812): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
17:52:28.340: E/AndroidRuntime(7812): at android.view.LayoutInflater.onCreateView(LayoutInflater.java:653)
17:52:28.340: E/AndroidRuntime(7812): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:678)
17:52:28.340: E/AndroidRuntime(7812): at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)
17:52:28.340: E/AndroidRuntime(7812): at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
17:52:28.340: E/AndroidRuntime(7812): at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
17:52:28.340: E/AndroidRuntime(7812): at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
17:52:28.340: E/AndroidRuntime(7812): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:255)
17:52:28.340: E/AndroidRuntime(7812): at android.app.Activity.setContentView(Activity.java:1835)
17:52:28.340: E/AndroidRuntime(7812): at com.v.splitter.AudioViewer.onCreate(AudioViewer.java:63)
17:52:28.340: E/AndroidRuntime(7812): at android.app.Activity.performCreate(Activity.java:4465)
17:52:28.340: E/AndroidRuntime(7812): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
17:52:28.340: E/AndroidRuntime(7812): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
17:52:28.340: E/AndroidRuntime(7812): ... 11 more
17:52:28.340: E/AndroidRuntime(7812): Caused by: java.lang.reflect.InvocationTargetException
17:52:28.340: E/AndroidRuntime(7812): at java.lang.reflect.Constructor.constructNative(Native Method)
17:52:28.340: E/AndroidRuntime(7812): at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
17:52:28.340: E/AndroidRuntime(7812): at android.view.LayoutInflater.createView(LayoutInflater.java:586)
17:52:28.340: E/AndroidRuntime(7812): ... 24 more
12-17:52:28.340: E/AndroidRuntime(7812): Caused by: java.lang.OutOfMemoryError
17:52:28.340: E/AndroidRuntime(7812): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
17:52:28.340: E/AndroidRuntime(7812): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:483)
17:52:28.340: E/AndroidRuntime(7812): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:351)
17:52:28.340: E/AndroidRuntime(7812): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:773)
17:52:28.340: E/AndroidRuntime(7812): at android.content.res.Resources.loadDrawable(Resources.java:1937)
17:52:28.340: E/AndroidRuntime(7812): at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
17:52:28.340: E/AndroidRuntime(7812): at android.view.View.<init>(View.java:2785)
17:52:28.340: E/AndroidRuntime(7812): at android.view.View.<init>(View.java:2722)
17:52:28.340: E/AndroidRuntime(7812): at android.view.ViewGroup.<init>(ViewGroup.java:379)
17:52:28.340: E/AndroidRuntime(7812): at android.widget.RelativeLayout.<init>(RelativeLayout.java:174)
17:52:28.340: E/AndroidRuntime(7812): ... 27 more
17:52:28.340:E/AndroidRuntime(7812):致命异常:main
17:52:28.340:E/AndroidRuntime(7812):java.lang.RuntimeException:无法启动活动组件信息{com.v.splitter/com.v.splitter.AudioViewer}:android.view.InflateException:二进制XML文件行#63:膨胀类时出错
17:52:28.340:E/AndroidRuntime(7812):在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
17:52:28.340:E/AndroidRuntime(7812):在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
17:52:28.340:E/AndroidRuntime(7812):在android.app.ActivityThread.access$600(ActivityThread.java:123)
17:52:28.340:E/AndroidRuntime(7812):在android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
17:52:28.340:E/AndroidRuntime(7812):位于android.os.Handler.dispatchMessage(Handler.java:99)
17:52:28.340:E/AndroidRuntime(7812):在android.os.Looper.loop(Looper.java:137)
17:52:28.340:E/AndroidRuntime(7812):位于android.app.ActivityThread.main(ActivityThread.java:4424)
17:52:28.340:E/AndroidRuntime(7812):位于java.lang.reflect.Method.Invokenactive(本机方法)
17:52:28.340:E/AndroidRuntime(7812):在java.lang.reflect.Method.invoke(Method.java:511)
17:52:28.340:E/AndroidRuntime(7812):位于com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
17:52:28.340:E/AndroidRuntime(7812):位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
17:52:28.340:E/AndroidRuntime(7812):在dalvik.system.NativeStart.main(本机方法)
17:52:28.340:E/AndroidRuntime(7812):由以下原因引起:android.view.InflateException:二进制XML文件行#63:膨胀类时出错
17:52:28.340:E/AndroidRuntime(7812):在android.view.LayoutInflater.createView(LayoutInflater.java:606)
17:52:28.340:E/AndroidRuntime(7812):位于com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
17:52:28.340:E/AndroidRuntime(7812):在android.view.LayoutInflater.onCreateView(LayoutInflater.java:653)
17:52:28.340:E/
bitmap.recycle();