我正在开发一个应用程序,其中一个活动是一个非常复杂的代码,其中不同的视图在单一布局中膨胀,如webview (使用带有图像的SD卡中的html文件),imageviews,滚动。在开始此活动时,我收到了这些错误。
E/AndroidRuntime(600): Caused by: java.lang.reflect.InvocationTargetException
E/AndroidRuntime(600): at java.lang.reflect.Constructor.constructNative(Native Method)
E/AndroidRuntime(600): at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
E/AndroidRuntime(600): at android.view.LayoutInflater.createView(LayoutInflater.java:586)
E/AndroidRuntime(600): ... 29 more
E/AndroidRuntime(600): Caused by: java.lang.OutOfMemoryError
E/AndroidRuntime(600): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
E/AndroidRuntime(600): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:483)
E/AndroidRuntime(600): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:351)
E/AndroidRuntime(600): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:773)
E/AndroidRuntime(600): at android.content.res.Resources.loadDrawable(Resources.java:1935)
E/AndroidRuntime(600): at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
E/AndroidRuntime(600): at android.view.View.<init>(View.java:2785)
E/AndroidRuntime(600): at android.view.View.<init>(View.java:2722)
E/AndroidRuntime(600): at android.view.ViewGroup.<init>(ViewGroup.java:379)
E/AndroidRuntime(600): at android.widget.RelativeLayout.<init>(RelativeLayout.java:174)
E/AndroidRuntime(600): ... 32 more
如何解决这个问题我试过这段代码,但还不知道该怎么做?
@Override
protected void onDestroy() {
super.onDestroy();
unbindDrawables(findViewById(R.id.rootView));
System.gc();
}
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
解决此问题的可能方法是什么?请帮忙
答案 0 :(得分:3)
在您的情况下使用位图优化内存使用情况的最佳方法是在每个ImageView调用finish()之前保存一个ImageViews列表:
((BitmapDrawable) myImageView.getDrawable()).getBitmap().recycle();
myImageView = null;
使用onPause
代码中的代码,活动的主要布局的ID为top_layout
:
@Override
protected void onPause() {
super.onPause();
unbindDrawables(findViewById(R.id.top_layout));
System.gc();
}
答案 1 :(得分:2)
在搜索并看到上述答案之后,我只是通过修改Android用户的代码编写了一个简单的代码片段。我已经使用了这个成功工作的代码。这个代码setCallback视图的背景,甚至回收所有当前使用的位图。
@Override
protected void onDestroy() {
super.onDestroy();
unbindDrawables(findViewById(R.id.rootView));
System.gc();
}
static void unbindDrawables(View view) {
try{
System.out.println("UNBINDING"+view);
if (view.getBackground() != null) {
((BitmapDrawable)view.getBackground()).getBitmap().recycle();
view.getBackground().setCallback(null);
view=null;
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
编辑:
我今天发现的使用小于20 kb大小的图像的新东西有利于内存优化,而不必经历内存不足错误。
答案 2 :(得分:1)
如果图像像素超出限制,则会出现OutOfMemoryException(最大分辨率为2048 * 2048)
您可以使用Bitmapfactory.Options -
来缩小图像的像素BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap myBitmap = BitmapFactory.decodeFile(mUri.getPath(),options);
Drawable d = new BitmapDrawable(Resources.getSystem(),myBitmap);
updateDrawable(d);
在活动中使用图像会降低其分辨率。
注意 - inSampleSize = 2表示它将大小减小1/2,分辨率减小1/4。
尝试将inSampleSize的值保持为2的幂也能获得最佳效果。
希望,它适合你。如有疑问,请发表评论。