Reputation: 109
When i start and run my app on the real device its say unfortunately stopped and in the logcat says java.lang.runoutofmemory and i don't know how to fix it
Here is my main activity class:
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
}
and now here's the grid view class
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;
}
}
and here's the log cat
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)
need your help please quickly
Upvotes: 0
Views: 196
Reputation: 4338
In addition to Gil's response, Google provides several suggestions as to how to handle Bitmaps from the following two links:
Displaying Bitmaps Efficiently and Loading Bitmaps Efficiently
This can be done with storing local version of a size accordance to the screen, manipulating inSampleSize and checking for OOM during loads to be able to respond appropriately at RunTime if you find yourself running out.
Upvotes: 1
Reputation: 16771
You're trying to load too many bitmaps during run-time. While Android devices might have a fair amount of memory, the OS only allocates a small amount for running apps, and so you'll likely experience an OutOfMemmoryError if you hold enough.
In my app, I needed to hold a buffer of 1024x1024 images, and started getting OutOfMemory errors after about 3-4 were loaded.
One option to solve this is to set a largeHeap setting in the manifest file, however the amount of memory which is added is limited, and varies between different devices. At the end, you might be able to load a couple more images, but you'll still reach the same dead end.
The real way to solve this is to come up with a way to not require many bitmaps at once during runtime. Figure out which images you need to display on screen at any given moment and only load those. Any bitmap which isn't actually being displayed, or about to be very shortly, should be removed. When removing bitmaps, be sure to call the recycle() function on them, as this frees up the bitmap's memory instantly.
This should get you started.
Upvotes: 2