私有內部類導致記憶體洩漏的解決方案
前言
前幾天在修復電池專案記憶體洩漏的地方學到了一個新的知識點.
私有內部類(匿名的私有內部類也算)中會有一個外部類的引用,那麼當內部類物件沒有被銷燬,外部類也不會被銷燬,這一點很容易忽略從而造成記憶體洩漏.
程式碼如下:這樣的匿名內部類使用會導致OutOfMemActivity的記憶體洩漏
public class OutOfMemActivity extends Activity implements View.OnClickListener{ public static final String ACTION_INTENT_FILTER = "ACTION_INTENT_FILTER"; private Button btn; private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { new Thread(){ @Override public void run() { super.run(); while (true){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } Log.i("tag","running ... "+OutOfMemActivity.this); } } }.start(); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_out_of_mem); btn = (Button)findViewById(R.id.btn_send); btn.setOnClickListener(this); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(ACTION_INTENT_FILTER); registerReceiver(broadcastReceiver,intentFilter); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(broadcastReceiver); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.btn_send: Intent intent = new Intent(); intent.setAction(ACTION_INTENT_FILTER); sendBroadcast(intent); break; } } }
我們可用通過弱引用解決該問題,我們改寫這個廣播接收器使它成為靜態內部類如下:
private static class MyBroadcastReceiver extends BroadcastReceiver{ private WeakReference<OutOfMemActivity> outOfMemActivityWeakReference; public MyBroadcastReceiver(WeakReference<OutOfMemActivity> outOfMemActivityWeakReference) { this.outOfMemActivityWeakReference = outOfMemActivityWeakReference; } @Override public void onReceive(Context context, Intent intent) { new Thread(){ @Override public void run() { super.run(); while (true){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } OutOfMemActivity outOfMemActivity = outOfMemActivityWeakReference.get(); Log.i("tag","running ... "+outOfMemActivity); } } }.start(); } }
這樣如果使用OutOfMemActivity物件,它是以弱引用傳送進來,在垃圾回收器掃描到該物件的時候就會回收掉它.
自己是從事了七年開發的Android工程師,不少人私下問我,2019年Android進階該怎麼學,方法有沒有?
沒錯,年初我花了一個多月的時間整理出來的學習資料,希望能幫助那些想進階提升Android開發,卻又不知道怎麼進階學習的朋友。【 包括高階UI、效能優化、架構師課程、NDK、Kotlin、混合式開發(ReactNative+Weex)、Flutter等架構技術資料 】,希望能幫助到您面試前的複習且找到一個好的工作,也節省大家在網上搜索資料的時間來學習。
資料獲取方式:加入Android架構交流QQ群聊:513088520 ,進群即領取資料!!!
點選連結加入群聊【Android移動架構總群】:加入群聊

資料大全