我在Play商店发布了我的应用程序。现在在Crashes和ANR中,我在2个设备上遇到错误(Galaxy Note3和Galaxy Note II)。我不知道如何解决这些错误,这是什么类型的错误?所以请帮我解决这些错误。在其他设备上,我没有收到任何报告。
错误 -
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:677)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:507)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:872)
at android.content.res.Resources.loadDrawable(Resources.java:3022)
at android.content.res.Resources.getDrawable(Resources.java:1586)
at android.view.View.setBackgroundResource(View.java:16120)
at com.info.laughingbuddha.Buddha4.onCreateView(Buddha4.java:21)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:472)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:163)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1068)
at android.support.v4.view.ViewPager.populate(ViewPager.java:914)
at android.support.v4.view.ViewPager$3.run(ViewPager.java:244)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803)
at android.view.Choreographer.doCallbacks(Choreographer.java:603)
at android.view.Choreographer.doFrame(Choreographer.java:572)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5293)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1259)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
at dalvik.system.NativeStart.main(Native Method)
Buddha4.java -
package com.info.laughingbuddha;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
public class Buddha4 extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.buddha, container, false);
TextViewEx t = (TextViewEx) rootView.findViewById(R.id.textView2);
t.setText("The Standing Happy Buddha brings riches and happiness.",true);
t.setMovementMethod(new ScrollingMovementMethod());
ImageView iv = (ImageView) rootView.findViewById(R.id.image1);
iv.setBackgroundResource(R.drawable.buddha4);
return rootView;
}
}
我不知道我需要发布什么代码,所以如果有人需要任何与此相关的代码,请发表评论。感谢。
答案 0 :(得分:6)
尝试使用以下代码行创建缩放位图:
Bitmap scaledBitmap = Bitmap.createScaledBitmap(myBitmap, width,
height, true);
检查以下链接:
android - out of memory exception when creating bitmap
Android out of memory exception with bitmaps
Can I catch out of memory exception in Android in Bitmap allocation for decoding a picture file?
答案 1 :(得分:2)
如果您有高分辨率图像,则应将其缩小以避免不同设备加载图像而不会遇到内存问题。 在您的情况下,某些手机在首次运行时可能不会表现出相同的行为,但最终,如果不处理优化的图像加载解决方案,应用程序将崩溃。
检查“内存问题”:
将缩小版本加载到内存中的主题。
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
Out of memory error on Android
关于如何避免它们:
How to avoid an out of memory error while using bitmaps in Android
概述:
http://blogs.innovationm.com/android-out-of-memory-error-causes-solution-and-best-practices/
http://android-developers.blogspot.de/2009/01/avoiding-memory-leaks.html
在将drawable设置为imageview的背景之前,即:
iv.setBackgroundResource(R.drawable.buddha4);
正如@ rup35h在答案中建议的那样,获取缩放位图或尝试其他选项,例如inSampleSize
,请检查您的解决方案如何影响图像质量。
答案 2 :(得分:2)
有时当我们使用这么多图像时在应用程序中的背景,它需要在Android RAM上占用大量空间。 这导致强制通过“Out of memory Bound Exception”关闭您的应用程序。
从你的崩溃日志中可以看出,你有一个非常大的drawable,所以为了避免OutOfMemory
你保留了不会占用太多内存的drawable。你可以按照一些人在答案中建议的那样缩小抽象。
如果你不想通过它并且你没有太大的可绘制大小,那么你可以选择将应用程序堆大小增加到大,这会增加堆内存。
如何增加堆大小
您可以在Android清单的应用程序标记中使用android:largeHeap="true"
(此处参考)来请求更大的堆大小,但这不适用于任何预先
蜂窝设备。
在2.3之前的设备上,您可以使用VMRuntime类,但这不适用于Gingerbread及以上版本。请参阅下面的操作方法。
VMRuntime.getRuntime().setMinimumHeapSize(BIGGER_SIZE);
在设置HeapSize之前,请确保您输入的大小不会影响其他应用程序或操作系统功能。
在设置之前,只需检查您的应用需要多大的尺寸&然后设置大小只是为了完成你的工作。不要使用这么多内存,否则其他应用程序可能会影响。
注意:最好不要再使用已经分配的位图内存,这可以是bitmap.recycle()
答案 3 :(得分:1)
我曾经遇到的一个问题是拥有大量MDPI可绘制资源但没有HDPI / XHDPI版本。在HDPI或XHDPI设备上加载这些设备时,Android会通过加载原始设备来扩展它们,然后在内存中制作一个放大的副本,这意味着您一次在内存中有两个副本,原始版本和按比例放大的版本。如果渲染器正在拉伸drawable(例如,如果它是视图的背景),那么在加载时Android不需要扩展它,因为渲染器无论如何都会这样做。因此,如果您只有一个图像的MDPI副本并且不希望Android进行扩展,则应将其放在drawable-nodpi文件夹而不是drawable或drawable-mdpi文件夹中。
修改强>
您可以通过设置android:scaleType属性来使用图像视图上可用的渲染时间缩放。例如。您可以将图像视图的宽度和高度设置为match_parent,然后将比例类型设置为centerCrop或centerInside,以便在保持其纵横比的同时将图像放大。 centerCrop将完全填充图像视图,但可能会截断一些图像,而centerInside确保整个图像可见,但可能留下一些空白。缩放将在渲染时完成,因此不会使用任何额外的内存。
这一切都可以在布局XML中完成,如下所示:
android:layout_height="match_parent"
android:layout_width="match_parent"
android:scaleType="centerCrop"
要使图像完全显示在图像视图内而不进行裁剪,请将最后一行更改为:
android:scaleType="centerInside"
最后,如果您不想保持纵横比,可以使用以下比例类型:
android:scaleType="fitXY"
答案 4 :(得分:0)
加载图像资源时必须缩小图像资源。
如果您使用Bitmap
变量加载图片,则可以使用inSample
使用BitmapFactory.Options
选项。不要使用Bitmap.createScaledBitmap
因为它会创建除原始位图之外的另一个位图!
尝试使用以下代码加载位图:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; //This will just get the size of your image
BitmapFactory.decodeFile(pictureFile.getAbsolutePath(), options);
//Get the downscale ratio
options.inJustDecodeBounds = false;
options.inSampleSize = calculateInSampleSize(options, widthOfTheImageView, heightOfTheImageView);
//Decode the bitmap using the downsampled image
Bitmap finalBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image_name options);
//Finally, set the bitmap
imageView.setImageBitmap(finalBitmap);
widthOfTheImageView
和heightOfTheImageView
代表ImageView
的大小。
calculateInSampleSize
方法(我是从Android开发者tutorial获得的):
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) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
答案 5 :(得分:0)
如果您不确定图像的大小,请不要直接加载Bitmap。当尺寸太大时请对其进行取样。在大多数情况下,加载的图像长度不应超过手机屏幕的长度。使用这样的代码来拍摄图像。
public static Bitmap loadImage(Context cx, Uri uri, int maxLength) {
InputStream is = cx.getContentResolver().openInputStream(uri);
Options opts = new Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, opts);
int length = Math.max(opts.outWidth, opts.outHeight);
int n = 1;
while (length > maxLength) {
maxLength /= 2;
n ++;
}
is = cx.getContentResolver().openInputStream(uri);
opts.inJustDecodeBounds = false;
opts.inPurgeable = true;
opts.inDither = true;
opts.inPurgeable = true;
opts.inSampleSize = sample;
Bitmap bm = BitmapFactory.decodeStream(is, null, opts);
return bm;
}
答案 6 :(得分:0)
退出活动时删除所有视图。在OnDestroy()中将其设为null
。
如果您使用的是Bitmaps
使用
bitmap.recycle();
当你使用它时。
你可以使用
android:largeHeap="true"
在manifest.xml中增加堆大小。