I have a gridview with some images inside. Sometime when I'm scrolling, GC_FOR_ALLOC or heap is increased and I don't know why. I used a method to load a minimized image.
Might I use Picasso or a ViewHolder ? RecyclerView ?
The memory issues happened once or twice when I tested my app on my personal device although everything still ran. But on an older smartphone ( less efficient) , the memory issues totally stopped the phone and other apps from running.
I see warnings on my "setTag" as though the problem is caused by a memory leak.
How can I repair the memory problems ?
MainActivity.java
public class MainActivity extends Activity {
GridView gridView;
MediaPlayer mPlayer;
@Override
public synchronized void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boolean internetAcces = checkDataConnection();
if(internetAcces == true){
setContentView(R.layout.activity_main);
AdView adView = (AdView) this.findViewById(R.id.adView);
AdRequest adRequest1 = new AdRequest.Builder().build();
adView.loadAd(adRequest1);
}
else{
setContentView(R.layout.activity_main2);
}
gridView = (GridView)findViewById(R.id.gridview);
gridView.setAdapter(new MyAdapter(this));
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
@Override
public synchronized void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
try{
if(mPlayer != null && mPlayer.isPlaying())
{
mPlayer.stop();
mPlayer.release();
playSong(position);
}
else
{
playSong(position);
}
}catch(Exception ex){
//Toast.makeText(MainActivity.this, ex.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}
@Override
protected void onPause(){
super.onPause();
}
@Override
protected void onStop() {
super.onStop();
System.exit(0);
}
@Override
protected void onDestroy(){
super.onDestroy();
System.exit(0);
}
Here's MyAdapter.java
public final class MyAdapter extends BaseAdapter {
private final List<Item> mItems = new ArrayList<Item>(30);
private final LayoutInflater mInflater;
public Context context;
public MyAdapter(Context context) {
mInflater = LayoutInflater.from(context);
this.context = context;
mItems.add(new Item("Hé pélo", R.drawable.hepelo));
mItems.add(new Item("Salut les losers", R.drawable.salutleslosers));
mItems.add(new Item("Arrête Abib", R.drawable.abib));
mItems.add(new Item("Goût bite", R.drawable.goutbite));
mItems.add(new Item("Makassy", R.drawable.makassy));
mItems.add(new Item("Joris Lecon", R.drawable.jorislecon));
mItems.add(new Item("Cache la drogue", R.drawable.cacheladrogue));
mItems.add(new Item("Un peu trop tactile", R.drawable.unpeutroptactile));
mItems.add(new Item("Qui c'est qu'a touché à Dorian ?", R.drawable.dorian));
mItems.add(new Item("T'es pas beau", R.drawable.tespasbeau));
mItems.add(new Item("Ta mère", R.drawable.tamere));
mItems.add(new Item("Je bute ce paquet de chips", R.drawable.jebutecepaquetdechips));
mItems.add(new Item("La maison du content", R.drawable.lamaisonducontent));
mItems.add(new Item("Mes péripétiiiiiies", R.drawable.mesperipeties));
mItems.add(new Item("La rapta babtou", R.drawable.laraptababtou));
mItems.add(new Item("Que vas-tu faire ?!", R.drawable.bangbang));
mItems.add(new Item("Oh les tétés !", R.drawable.lestetes));
mItems.add(new Item("Mollé mollé", R.drawable.laraptababtou));
mItems.add(new Item("Okéééé", R.drawable.ok));
mItems.add(new Item("Guillaume le thug", R.drawable.guillaumelethug));
mItems.add(new Item("C'est ma teub", R.drawable.cestmateub));
mItems.add(new Item("Je suis qu'un thug", R.drawable.jsuisquunthug));
}
@Override
public int getCount() {
return mItems.size();}
@Override
public Item getItem(int i) {
return mItems.get(i);
}
@Override
public long getItemId(int i) {
return mItems.get(i).drawableId;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
View v = view;
ImageView picture;
TextView name;
if (v == null) {
v = mInflater.inflate(R.layout.grid_item, viewGroup, false);
v.setTag(R.id.picture, v.findViewById(R.id.picture));
v.setTag(R.id.text, v.findViewById(R.id.text));
}
picture = (ImageView) v.getTag(R.id.picture);
name = (TextView) v.getTag(R.id.text);
Item item = getItem(i);
//picture.setImageResource(item.drawableId);
picture.setImageBitmap(decodeSampledBitmapFromResource(context.getResources(),item.drawableId, 150, 150));
name.setText(item.name);
return v;}
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;}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
private static class Item {
public final String name;
public final int drawableId;
Item(String name, int drawableId) {
this.name = name;
this.drawableId = drawableId;
}
}
}
main_activity.xml :
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<GridView
android:id="@+id/gridview"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_gravity="center"
android:verticalSpacing="0dp"
android:layout_weight="1"
android:horizontalSpacing="0dp"
android:stretchMode="columnWidth"
android:numColumns="2"
android:listSelector="@android:color/transparent"
android:scrollingCache="false"
android:animationCache="false"
/>
<com.google.android.gms.ads.AdView
android:id="@+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
ads:adSize="SMART_BANNER"
ads:adUnitId="ca-app-pub-2373549811754777/2717783647"
/>
grid_item.xml :
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.slamingresources.laboiteamisterv.SquareImageView
android:id="@+id/picture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
/>
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="4dp"
android:paddingBottom="5dp"
android:layout_gravity="bottom"
android:textColor="@android:color/white"
android:background="#55000002"
/>
Logcat :
11-20 03:21:45.878: I/dalvikvm-heap(16815): Clamp target GC heap from 128.451MB to 128.000MB
11-20 03:21:47.628: I/dalvikvm-heap(16815): Clamp target GC heap from 135.930MB to 128.000MB
11-20 03:21:47.688: D/dalvikvm(16815): GC_BEFORE_OOM freed 109065K, 85% free 20521K/131004K, paused 59ms, total 60ms
11-20 03:22:00.498: D/dalvikvm(16815): GC_FOR_ALLOC freed 3972K, 85% free 20494K/131004K, paused 24ms, total 24ms
I know this is old but for those that are still looking for same answers: you can use getcachedir()
to store data temporarily in Android.
For more options see Android data storage .
Yes, you got this error! Why? AFAIK, before Android 3.0 (I dont remember exactly) bitmap is not auto recycle
. You must recycle bitmap after not using it. To resolve your problem, I suggest you cache your Bitmap
. When cached
hit, recycle unused one.
: I think the easiest way to solve your problem is use another library to help loading image. :我认为解决您的问题的最简单方法是使用另一个库来帮助加载图像。 You can look at Universal ImageLoader . There's a function which can help you load with target size:
// Load image, decode it to Bitmap and return Bitmap synchronously
ImageSize targetSize = new ImageSize(80, 50); // result Bitmap will be fit to this size
Bitmap bmp = imageLoader.loadImageSync(imageUri, targetSize, options);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.