【问题标题】:run out of memory android project内存不足的android项目
【发布时间】:2014-08-20 20:03:21
【问题描述】:

当我在真实设备上启动并运行我的应用程序时,它说不幸地停止了,并且在 logcat 中说 java.lang.runoutofmemory 并且我不知道如何修复它

这是我的主要活动课程:

public class MainActivity extends Activity implements OnItemClickListener,
TextWatcher {


String[] category_name;
int[] category_id;
Bitmap[] pics;
GridView v1;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

ActionBar bar = getActionBar();
// for color
bar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#5c7afe")));
// for image

setContentView(R.layout.activity_main);

v1 = (GridView) findViewById(R.id.gridvieww);
SetDB();
v1.setOnItemClickListener(this);
}

public void SetDB() {
SQLiteDatabase DB = openOrCreateDatabase("test", MODE_PRIVATE, null);// to
                                                                        // create
                                                                        // db
                                                                        // folder
InputStream is = getResources().openRawResource(R.raw.hotline_data);
try {
    byte[] b = new byte[is.available()];
    is.read(b);
    FileOutputStream fos = new FileOutputStream("/data/data/"
            + getPackageName() + "/databases/Hotline.sqlite");
    fos.write(b);
    fos.close();

    SQLiteDatabase hotline_db = openOrCreateDatabase("Hotline.sqlite",
            MODE_PRIVATE, null);
    Cursor c = hotline_db.rawQuery("select * from category", null);
    if (c.moveToFirst()) {
        category_name = new String[c.getCount()];
        category_id = new int[c.getCount()];
        pics = new Bitmap[c.getCount()];
        int i = 0;
        do {
            int id = c.getInt(c.getColumnIndex("id"));
            String name = c.getString(c.getColumnIndex("name"));
            byte[] b1 = c.getBlob(c.getColumnIndex("pic"));
            Bitmap bm = BitmapFactory.decodeByteArray(b1, 0, b1.length);
            category_name[i] = name;
            category_id[i] = id;
            pics[i] = bm;
            i++;
        } while (c.moveToNext());
        CustomGridAdapter cga = new CustomGridAdapter(this,
                category_name, pics);
        v1.setAdapter(cga);
     }

  } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }

 }

@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
Intent i = new Intent(this, Company.class);
i.putExtra("cat_id", category_id[arg2]);
startActivity(i);
}

@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub

}

@Override
public void beforeTextChanged(CharSequence s, int start, int count,
    int after) {
// TODO Auto-generated method stub

}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub

}

现在这里是网格视图类

public class CustomGridAdapter extends BaseAdapter {
private Context context;
private final String [] gridValues;
private Bitmap[] pic;
public CustomGridAdapter (Context context,String[] gridValues,Bitmap[] pic){
this.context= context;
this.gridValues=gridValues;
this.pic=pic;


}
@Override
public int getCount() {
    // TODO Auto-generated method stub
    return gridValues.length;
}

@Override
public Object getItem(int arg0) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public long getItemId(int arg0) {
    // TODO Auto-generated method stub
    return 0;
}

@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
    // TODO Auto-generated method stub

    LayoutInflater li=(LayoutInflater)                                  
    View v=li.inflate(R.layout.grid, arg2, false);
    context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    ImageView iv=(ImageView) v.findViewById(R.id.gridimage);

    iv.setImageBitmap(pic[arg0]);

    return v;
    }

    }

这是日志猫

08-20 18:09:41.738: E/AndroidRuntime(11021):    at android.view.Choreographer.doFrame(Choreographer.java:573)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at android.os.Handler.handleCallback(Handler.java:733)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at android.os.Handler.dispatchMessage(Handler.java:95)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at android.os.Looper.loop(Looper.java:157)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at android.app.ActivityThread.main(ActivityThread.java:5356)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at java.lang.reflect.Method.invokeNative(Native Method)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at java.lang.reflect.Method.invoke(Method.java:515)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at dalvik.system.NativeStart.main(Native Method)
08-20 18:09:41.738: E/AndroidRuntime(11021): Caused by: java.lang.reflect.InvocationTargetException
08-20 18:09:41.738: E/AndroidRuntime(11021):    at java.lang.reflect.Constructor.constructNative(Native Method)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at android.view.LayoutInflater.createView(LayoutInflater.java:600)
08-20 18:09:41.738: E/AndroidRuntime(11021):    ... 41 more
08-20 18:09:41.738: E/AndroidRuntime(11021): Caused by: java.lang.OutOfMemoryError
08-20 18:09:41.738: E/AndroidRuntime(11021):    at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:677)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:507)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:872)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at android.content.res.Resources.loadDrawable(Resources.java:3056)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at android.content.res.TypedArray.getDrawable(TypedArray.java:602)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at android.widget.ImageView.<init>(ImageView.java:133)
08-20 18:09:41.738: E/AndroidRuntime(11021):    at android.widget.ImageView.<init>(ImageView.java:123)

需要你的帮助请快

【问题讨论】:

  • 你是在设备还是模拟器上运行它?
  • 在问题发布后仅 5 分钟戳答案可能被认为是粗鲁的......

标签: java android eclipse android-layout android-intent


【解决方案1】:

您试图在运行时加载太多位图。虽然 Android 设备可能有相当多的内存,但操作系统只会为运行的应用程序分配少量内存,因此如果您拥有足够的内存,您可能会遇到 OutOfMemmoryError。

在我的应用程序中,我需要保存一个 1024x1024 图像的缓冲区,并在加载大约 3-4 个图像后开始出现 OutOfMemory 错误。

解决这个问题的一个方法是在清单文件中设置一个 largeHeap 设置,但是添加的内存量是有限的,并且在不同的设备之间会有所不同。最后,您也许可以再加载几张图片,但您仍然会遇到同样的死胡同。

解决这个问题的真正方法是想出一种在运行时一次不需要很多位图的方法。找出在任何给定时刻您需要在屏幕上显示的图像并仅加载这些图像。任何实际上没有显示或即将显示的位图都应该被删除。删除位图时,请务必对其调用 recycle() 函数,因为这会立即释放位图的内存。

这应该让你开始。

【讨论】:

  • 好的,现在我必须添加所有位图如何完成或任何其他建议来处理此错误@Gil
  • 不是预加载所有位图,而是仅在通过适配器为视图分配数据时加载它们。创建视图并分配数据后,使用 AsyncTask 加载位图,为 ImageVIew 提供一些默认图片,直到加载结束,并在加载结束时,将新位图分配给 ImageView。如果 ImageView 有分配给它的先前位图,请确保在开始加载新位图之前回收它并将 ImageView 的位图设置为 null。
  • thx gil 当我增加 android 堆时它对我有用,但它会在其他设备上运行吗?
  • 就像我之前说的那样,这样做只会增加一点内存消耗。这里的问题是您没有正确使用android的内存池。在编写 Android 应用程序时,预加载这么多位图绝不是一个好主意。您应该始终加载您绝对需要的图像,并立即丢弃那些您不需要的图像。用户会原谅 1 秒钟内没有看到他们想要的图像。他们不太可能原谅不稳定且容易崩溃的应用程序。
  • 好的,感谢您的信息,我将尝试在新的更新中解决此问题。我明天必须把它放在商店里并尝试下载它:D(Hotlinak)
【解决方案2】:

除了 Gil 的回复之外,Google 还通过以下两个链接提供了一些关于如何处理位图的建议:

Displaying Bitmaps EfficientlyLoading Bitmaps Efficiently

这可以通过根据屏幕存储本地版本的大小、操作 inSampleSize 并在加载期间检查 OOM 来完成,以便在您发现自己用完时能够在运行时做出适当的响应。

【讨论】:

  • 怎么做我不明白怎么做
猜你喜欢
  • 2017-05-12
  • 1970-01-01
  • 2019-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多