看過一些大神分享的文章,吸收一些經驗ide
一、處理Handler形成的內存泄露oop
建立一個靜態Handler內部類,而後對Handler持有的對象使用弱引用,這樣在回收時也能夠回收Handler持有的對象,這樣雖然避免了Activity泄漏,不過Looper線程的消息隊列中仍是可能會有待處理的消息,因此咱們在Activity的Destroy時或者Stop時應該移除消息隊列中的消息this
public class MainActivity extends AppCompatActivity {spa
private MyHandler mHandler = new MyHandler(this);線程
private TextView mTextView;orm
private static class MyHandler extends Handler {對象
private WeakReference<Context> reference;生命週期
public MyHandler(Context context) {隊列
reference = new WeakReference<>(context);內存
}
@Override
public void handleMessage(Message msg) {
MainActivity activity = (MainActivity) reference.get();
if (activity != null) {
activity.mTextView.setText("");
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.textview);
loadData();
}
private void loadData() {
// ...request
Message message = Message.obtain();
mHandler.sendMessage(message);
}
@Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacksAndMessages(null);
}
}
二、線程形成的內存泄漏
static class MyAsyncTask extends AsyncTask<Void, Void, Void> {
private WeakReference<Context> weakReference;
public MyAsyncTask(Context context) {
weakReference = new WeakReference<>(context);
}
@Override
protected Void doInBackground(Void... params) {
SystemClock.sleep(10000);
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
MainActivity activity = (MainActivity) weakReference.get();
if (activity != null) {
//...
}
}
}
static class MyRunnable implements Runnable{
@Override
public void run() {
SystemClock.sleep(10000);
}
}
//——————
new Thread(new MyRunnable()).start();
new MyAsyncTask(this).execute();
一些建議
對於生命週期比Activity長的對象若是須要應該使用ApplicationContext
對於須要在靜態內部類中使用非靜態外部成員變量(如:Context、View ),能夠在靜態內部類中使用弱引用來引用外部類的變量來避免內存泄漏
對於再也不須要使用的對象,顯示的將其賦值爲null,好比使用完Bitmap後先調用recycle(),再賦爲null
保持對對象生命週期的敏感,特別注意單例、靜態對象、全局性集合等的生命週期
對於生命週期比Activity長的內部類對象,而且內部類中使用了外部類的成員變量,能夠這樣作避免內存泄漏:
將內部類改成靜態內部類
靜態內部類中使用弱引用來引用外部類的成員變量
在涉及到Context時先考慮ApplicationContext