致命异常:android.graphics.BitmapFactory.nativeDecodeStream中的main java.lang.OutOfMemoryError(Native Method)
我在运行我的应用程序时不断收到此错误。该应用程序将编译正常,一旦我开始与它交互(ImageSlider)有时它会中断并提出该消息。致命异常:android.graphics.BitmapFactory.nativeDecodeStream中的main java.lang.OutOfMemoryError(Native Method)
logcat的
02-18 12:25:05.426: E/AndroidRuntime(4545): FATAL EXCEPTION: main
02-18 12:25:05.426: E/AndroidRuntime(4545): java.lang.OutOfMemoryError
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:493)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:299)
02-18 12:25:05.426: E/AndroidRuntime(4545): at com.oneplc.viessmannapp.imageslider.adapter.FullScreenImageAdapter.instantiateItem(FullScreenImageAdapter.java:59)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:832)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.support.v4.view.ViewPager.populate(ViewPager.java:1016)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.support.v4.view.ViewPager.populate(ViewPager.java:914)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.support.v4.view.ViewPager$3.run(ViewPager.java:244)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.support.v4.view.ViewPager.completeScroll(ViewPager.java:1761)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.support.v4.view.ViewPager.onInterceptTouchEvent(ViewPager.java:1894)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1629)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1684)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1684)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1684)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1684)
02-18 12:25:05.426: E/AndroidRuntime(4545): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1917)
02-18 12:25:05.426: E/AndroidRuntime(4545): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1371)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.app.Activity.dispatchTouchEvent(Activity.java:2364)
02-18 12:25:05.426: E/AndroidRuntime(4545): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1865)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.view.View.dispatchPointerEvent(View.java:5721)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:2890)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2466)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.view.ViewRootImpl.processInputEvents(ViewRootImpl.java:845)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2475)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.os.Handler.dispatchMessage(Handler.java:99)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.os.Looper.loop(Looper.java:137)
02-18 12:25:05.426: E/AndroidRuntime(4545): at android.app.ActivityThread.main(ActivityThread.java:4424)
02-18 12:25:05.426: E/AndroidRuntime(4545): at java.lang.reflect.Method.invokeNative(Native Method)
02-18 12:25:05.426: E/AndroidRuntime(4545): at java.lang.reflect.Method.invoke(Method.java:511)
02-18 12:25:05.426: E/AndroidRuntime(4545): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
02-18 12:25:05.426: E/AndroidRuntime(4545): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
02-18 12:25:05.426: E/AndroidRuntime(4545): at dalvik.system.NativeStart.main(Native Method)
在行类,负责/ FullScreenImageAdapter.java:59
public class FullScreenImageAdapter extends PagerAdapter {
private Activity _activity;
private ArrayList<String> _imagePaths;
private LayoutInflater inflater;
// constructor
public FullScreenImageAdapter(Activity activity,
ArrayList<String> imagePaths) {
this._activity = activity;
this._imagePaths = imagePaths;
}
@Override
public int getCount() {
return this._imagePaths.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == ((RelativeLayout) object);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
TouchImageView imgDisplay;
Button btnClose;
inflater = (LayoutInflater) _activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View viewLayout = inflater.inflate(R.layout.layout_fullscreen_image, container,
false);
imgDisplay = (TouchImageView) viewLayout.findViewById(R.id.imgDisplay);
btnClose = (Button) viewLayout.findViewById(R.id.btnClose);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(_imagePaths.get(position), options);
imgDisplay.setImageBitmap(bitmap);
// close button click event
btnClose.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
_activity.finish();
}
});
((ViewPager) container).addView(viewLayout);
return viewLayout;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((RelativeLayout) object);
}
}
评论
我看到一些其他的线程,但他们哪里都不有益的,或者至少不可以在我的情况下实施。
任何想法如何克服这个问题?
你应该看看这篇关于android dev网站http://developer.android.com/training/displaying-bitmaps/index.html的文章。你应该异步加载位图,因为你的解码文件,其昂贵的操作,你也应该先加载位图的尺寸和比它扩展到的imageview的
你应该使用这个真实大小......
@Override
public Object instantiateItem(ViewGroup container, int position) {
final TouchImageView imgDisplay;
inflater = (LayoutInflater) _activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View viewLayout = inflater.inflate(
R.layout.layout_fullscreen_image, container, false);
imgDisplay = (TouchImageView) viewLayout
.findViewById(R.id.imgDisplay);
final ProgressBar spinner = (ProgressBar) viewLayout
.findViewById(R.id.loading);
// btnShare = (Button) viewLayout.findViewById(R.id.btnShare);
imageLoader.displayImage(_imagePaths.get(position).get("url"),
imgDisplay, options, new ImageLoadingListener() {
@Override
public void onLoadingStarted() {
spinner.setVisibility(View.VISIBLE);
}
@Override
public void onLoadingFailed(FailReason failReason) {
String message = null;
switch (failReason) {
case IO_ERROR:
message = "Input/Output error";
break;
case OUT_OF_MEMORY:
message = "Out Of Memory error";
break;
case UNKNOWN:
message = "Unknown error";
break;
}
Toast.makeText(FullScreenViewActivity.this,
message, Toast.LENGTH_SHORT).show();
spinner.setVisibility(View.GONE);
imgDisplay
.setImageResource(android.R.drawable.ic_delete);
}
@Override
public void onLoadingComplete(Bitmap loadedImage) {
spinner.setVisibility(View.GONE);
Animation anim = AnimationUtils
.loadAnimation(FullScreenViewActivity.this,
R.anim.fade_in);
imgDisplay.setAnimation(anim);
anim.start();
}
@Override
public void onLoadingCancelled() {
// Do nothing
}
});
((ViewPager) container).addView(viewLayout, 0);
return viewLayout;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((FrameLayout) object);
}
}
添加在onCreate()方法这个代码..
private DisplayImageOptions options;
options = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.ic_launcher).cacheOnDisc()
.imageScaleType(ImageScaleType.IN_SAMPLE_INT).build();
添加通用图像装载机-1.6.1-与-src.jar jar文件到您的库文件夹。
UPDATE:
private DisplayImageOptions options;
public FullScreenImageAdapter(Activity activity,
ArrayList<String> imagePaths) {
this._activity = activity;
this._imagePaths = imagePaths;
options = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.ic_launcher).cacheOnDisc()
.imageScaleType(ImageScaleType.IN_SAMPLE_INT).build();
}
我会尝试它现在Piyush! – AndroidKrayze
Piyush,我的类扩展适配器,不是一个活动,所以这意味着我没有一个onCreate方法。 – AndroidKrayze
您也可以将它添加到您的Adapter类构造函数中。 – Piyush
如果有人试图从sqlite的图像和获取内存不足错误尝试以下操作:
cursor = adapter.getAllrecords(); //get your table records in cursor
//moving to the current position in cursor
cursor.moveToPosition(position);
byte [] image = cursor.getBlob(cursor.getColumnIndex("image"));
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
bitmapImage = BitmapFactory.decodeByteArray(image, 0, image.length, options);
imageView.setImageBitmap(decodeSampledBitmapFromResource(80, 80));//pass height and
//width as per your requirement
public 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;
}
public Bitmap decodeSampledBitmapFromResource(int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true
to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(image, 0, image.length, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeByteArray(image, 0, image.length, options);
}
这段代码根据开发商guideliness工作了me..however我们应该使用AsyncTask处理与图像相关的任务...我们不应该在UI线程上运行它。
如果谷歌文档没有帮助(他们有一些巧妙的技巧),作为最后的手段,你可以尝试添加 android:largeHeap="true"
在AndroidManifest.xml
的<application>
标签。但真的,最后的手段。
你可以使用通用imageLoader类..... – Piyush
那么这是在全屏幕活动实施?我现在正在实施相同的事情,并为我工作得很好。 – Piyush
它很奇怪,因为我自己运行此功能,它工作正常,但是当我将它合并到我的应用程序,我得到内存错误.. – AndroidKrayze