編輯:關於Android編程
Handler也是造成內存洩露的一個重要的源頭,主要Handler屬於TLS(Thread Local Storage)變量,生命周期和Activity是不一致的
,Handler引用Activity會存在內存洩露。
/** * * 實現的主要功能。 * @version 1.0.0 * @author Abay Zhuang
* Create at 2014-7-28 */ public class HandlerActivity extends Activity { private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // ... } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mHandler.sendMessageDelayed(Message.obtain(), 60000); //just finish this activity finish(); } }
是否您以前也是這樣用的呢。
Eclipse 工具有這樣的警告提示 警告:
This Handler class should be static or leaks might occur (com.example.ta.HandlerActivity.1)
意思:class 使用靜態聲明否者可能出現內存洩露。
如果外部類是Activity,則會引起Activity洩露 。
當Activity finish後,延時消息會繼續存在主線程消息隊列中1分鐘,然後處理消息。而該消息引用了Activity的Handler對象,然後這個Handler又引用了這個Activity。這些引用對象會保持到該消息被處理完,這樣就導致該Activity對象無法被回收,從而導致了上面說的 Activity洩露。
/** * * 實現的主要功能。 * * @version 1.0.0 * @author Abay Zhuang
* Create at 2014-7-28 */ public class HandlerActivity2 extends Activity { private static final int MESSAGE_1 = 1; private static final int MESSAGE_2 = 2; private static final int MESSAGE_3 = 3; private final Handler mHandler = new MyHandler(this); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mHandler.sendMessageDelayed(Message.obtain(), 60000); // just finish this activity finish(); } public void todo() { }; private static class MyHandler extends Handler { private final WeakReferencemActivity; public MyHandler(HandlerActivity2 activity) { mActivity = new WeakReference (activity); } @Override public void handleMessage(Message msg) { System.out.println(msg); if (mActivity.get() == null) { return; } mActivity.get().todo(); } }
當Activity finish後 handler對象還是在Message中排隊。 還是會處理消息,這些處理有必要?
正常Activitiy finish後,已經沒有必要對消息處理,那需要怎麼做呢?
解決方案也很簡單,在Activity onStop或者onDestroy的時候,取消掉該Handler對象的Message和Runnable。
通過查看Handler的API,它有幾個方法:removeCallbacks(Runnable r)和removeMessages(int what)等。
代碼如下:
/** * 一切都是為了不要讓mHandler拖泥帶水 */ @Override public void onDestroy() { mHandler.removeMessages(MESSAGE_1); mHandler.removeMessages(MESSAGE_2); mHandler.removeMessages(MESSAGE_3); // ... ... mHandler.removeCallbacks(mRunnable); // ... ... }
如果上面覺的麻煩,也可以如下面:
@Override public void onDestroy() { // If null, all callbacks and messages will be removed. mHandler.removeCallbacksAndMessages(null); }
敬請期待下一章(^__^) 嘻嘻……
也可以關注我的github
這篇文章是繼自定義EditText樣式之後的功能強化,對於實際應用項目有很大的參考意見,感興趣的朋友可以移步上一篇,”Android Studion自定義Ed
目前,市場上很多Android手機軟件都具有清理SD卡緩存的功能,比如360,金山等等。那麼這些軟件是如何實現清理sd卡緩存數據功能的呢?下面,我就給大家演示下,這些功能
demo的邏輯過程:1.進入程序2.檢查是否有版本更新,如果有則詢問用戶是否更新,否則維持原狀3.檢測當前網絡狀態並且詢問用戶是否進行版本更新,如果是則進行更新,否則維持
步驟如下:將以上所有so庫分別放到arm64-v8a,armeabi,armeabi-v7a,x86,x86_64文件夾下 將assets文件夾裡的資源拷貝到/項目名/a