二、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 -
} -
} - }
- 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 -
} - }
五、超级大胖子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(); - }
七、其它要说的。