我有一个内部有一些图像的gridview。有时当我滚动时,GC_FOR_ALLOC或堆增加了,我不知道为什么。我使用一种方法来加载最小化的图像。
我可以使用Picasso或ViewHolder吗? RecyclerView?
当我在我的个人设备上测试我的应用程序时,内存问题发生了一两次,尽管一切都还在运行。但是在较旧的智能手机上(效率较低),内存问题完全阻止了手机和其他应用的运行。
我在“setTag”上看到警告,好像问题是由内存泄漏引起的。
如何修复内存问题?
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);
}
这是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
答案 0 :(得分:1)
我知道这已经过时了但对于那些仍在寻找相同答案的人:您可以使用getcachedir()
暂时在Android中存储数据。
有关更多选项,请参阅Android data storage。
答案 1 :(得分:0)
是的,你收到了这个错误!为什么? AFAIK,在Android 3.0之前(我完全不记得)位图不是自动recycle
。不使用后必须回收位图。
要解决您的问题,建议您缓存Bitmap
。当cached
命中时,回收未使用的。
编辑:我认为解决问题的最简单方法是使用另一个库来帮助加载图像。你可以看看Universal ImageLoader。有一个功能可以帮助您加载目标大小:
// 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);