Android内存优化
Posted wulianghuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android内存优化相关的知识,希望对你有一定的参考价值。
一、
二、Android的内存溢出
为什么会出现内存不够用的情况呢?我想原因主要有两个:
- 由于我们程序的失误,长期保持某些资源(如Context)的引用,造成内存泄露,资源造成得不到释放。
- 保存了多个耗用内存过大的对象(如Bitmap),造成内存超出限制。
三、万恶的static
- public
class ClassName -
private static Context mContext; -
//省略 -
以上的代码是很危险的,如果将Activity赋值到么mContext的话。那么即使该Activity已经onDestroy,但是由于仍有对象保存它的引用,因此该Activity依然不会被释放。
- private
static Drawable sBackground; -
-
@Override -
protected void onCreate(Bundle state) -
super.onCreate(state); -
-
TextView label = new TextView(this); -
label.setText("Leaks are bad"); -
-
if (sBackground == null) -
sBackground = getDrawable(R.drawable.large_bitmap); -
-
label.setBackgroundDrawable(sBackground); -
-
setContentView(label); -
四、都是线程惹的祸
- public
class MyActivity extends Activity -
@Override -
public void onCreate(Bundle savedInstanceState) -
super.onCreate(savedInstanceState); -
setContentView(R.layout.main); -
new MyThread().start(); -
-
-
private class MyThread extends Thread -
@Override -
public void run() -
super.run(); -
//do somthing -
-
-
有些人喜欢用Android提供的AsyncTask,但事实上AsyncTask的问题更加严重,Thread只有在run函数不结束时才出现这种内存泄露问题,然而AsyncTask内部的实现机制是运用了ThreadPoolExcutor,该类产生的Thread对象的生命周期是不确定的,是应用程序无法控制的,因此如果AsyncTask作为Activity的内部类,就更容易出现内存泄露的问题。
- public
abstract class WeakAsyncTask Progress, Result, WeakTarget> extends -
AsyncTask Progress, Result> -
protected WeakReference mTarget; -
-
public WeakAsyncTask(WeakTarget target) -
mTarget = new WeakReference(target); -
-
-
-
@Override -
protected final void onPreExecute() -
final WeakTarget target = mTarget.get(); -
if (target != null) -
this.onPreExecute(target); -
-
-
-
-
@Override -
protected final Result doInBackground(Params... params) -
final WeakTarget target = mTarget.get(); -
if (target != null) -
return this.doInBackground(target, params); -
else -
return null; -
-
-
-
-
@Override -
protected final void onPostExecute(Result result) -
final WeakTarget target = mTarget.get(); -
if (target != null) -
this.onPostExecute(target, result); -
-
-
-
protected void onPreExecute(WeakTarget target) -
// No default action -
-
-
protected abstract Result doInBackground(WeakTarget target, Params... params); -
-
protected void onPostExecute(WeakTarget target, Result result) -
// No default action -
-
由于51cto不让我一次传完,说我的字数太多了,所以分开传了。
五、超级大胖子Bitmap
-
private ImageView preview; -
BitmapFactory.Options options = new BitmapFactory.Options(); -
options.inSampleSize = 2;//图片宽高都为原来的二分之一,即图片为原来的四分之一 -
Bitmap bitmap = BitmapFactory.decodeStream(cr.openInputStream(uri), null, options); - preview.setImageBitmap(bitmap);
-
- private
class MyAdapter extends BaseAdapter -
-
private ArrayList> mBitmapRefs = new ArrayList>(); -
private ArrayList mValues; -
private Context mContext; -
private LayoutInflater mInflater; -
-
MyAdapter(Context context, ArrayList values) -
mContext = context; -
mValues = values; -
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); -
-
public int getCount() -
return mValues.size(); -
-
-
public Object getItem(int i) -
return mValues.get(i); -
-
-
public long getItemId(int i) -
return i; -
-
-
public View getView(int i, View view, ViewGroup viewGroup) -
View newView = null; -
if(view != null) -
newView = view; -
else -
newView =(View)mInflater.inflate(R.layout.image_view, false); -
-
-
Bitmap bitmap = BitmapFactory.decodeFile(mValues.get(i).fileName); -
mBitmapRefs.add(new SoftReference(bitmap)); //此处加入ArrayList -
((ImageView)newView).setImageBitmap(bitmap); -
-
return newView; -
-
六、行踪诡异的Cursor
- Cursor
cursor = null; - try
-
cursor = mContext.getContentResolver().query(uri,null, null,null,null); -
if(cursor != null) -
cursor.moveToFirst(); -
//do something -
-
catch (Exception e) -
e.printStackTrace(); -
finally -
if (cursor != null) -
cursor.close(); -
-
- @Override
- protected
void onDestroy() -
if (mAdapter != null && mAdapter.getCurosr() != null) -
mAdapter.getCursor().close(); -
-
super.onDestroy(); -
七、其它要说的。
以上是关于Android内存优化的主要内容,如果未能解决你的问题,请参考以下文章