編輯:關於Android編程
如果在Activiy中通過內部類(Runnable)的方式定義了一個變量runnable,
final Runnable runnable = new Runnable() { public void run() { // ... do some work } }; handler.postDelayed(runnable, TimeUnit.SECONDS.toMillis(10)
因為Runnable不是static類型,所以會有一個包含Activity實例的implicit reference --- Activity.this。
如果Activity在runnable變量run之前(10s內)被finish掉了但是Activity.this仍然存在,那麼Activity的對象就不會被GC回收,從而導致memory leak。
即使使用一個靜態內部類,也不能保證萬事大吉。
static class MyRunnable implements Runnable { private View view; public MyRunnable(View view) { this.view = view; } public void run() { // ... do something with the view } }
假設在runnable執行之前,View被移除了,但是成員變量view還在繼續引用它,仍然會導致memory leak。
上面的兩個例子當中,導致內存洩露的兩種用法分別是隱式引用(implicit reference) 和 顯式引用(explicit reference)。
解決隱式引用的方法比較簡單,只要使用內部非靜態類(non-static inner class)或者 top-level class(在一個獨立的java文件中定義的變量)就可以將隱式變為顯式,從而避免內存洩露。
如果繼續使用非靜態內部類,那麼就要在onPause的時候手動結束那些掛起的任務(pending task)。
關於如何結束任何,Handler可參考這篇文章中的Canceling a pending Runnable和Canceling pending Messages。HandlerThread可參考這篇文章。
解決第二個問題要用到WeakReference,WeakReference的用法可以google一下,簡而言之就是:只要還有其他的stronger reference,WeakReference就可以繼續引用。
static class MyRunnable implements Runnable { private WeakReference>View< view; public MyRunnable(View view) { this.view = new WeakReference>View<(view); } public void run() { View v = view.get(); if (v != null) { // ... do something with the view } } }
這樣一來問題就解決了,美中不足的是每次使用view之前都要做空指針判斷。另外一個比較高效的方法就是在onResume中為runnable的view賦值,在onPause中賦值為null。
private static class MyHandler extends Handler { private TextView view; public void attach(TextView view) { this.view = view; } public void detach() { view = null; } @Override public void handleMessage(Message msg) { // .... }
在繼承Handler或者HandlerThread的時候,
盡量定義一個static類或者top-level類。如果用到了ui元素,一定要在Activity的生命周期接觸之前釋放掉。Asynchronous Android - Steve Liles
最近項目上有需求 ,要求狀態欄透明化 。還有需求是拖動狀態欄標題一下的內容,標題欄的顏色要變化 。這裡所謂的既是狀態欄著色,也是我們經常聽到的沉浸式狀態欄,關於沉浸式的稱
Auticompelete TextView動態匹配輸入的內容:目的,動態匹配輸入的內容,如百度搜索引擎當輸入文本時可以根據內容顯示匹配的熱門信息。一.目的效果圖:實驗效
其實webview加載資源的速度並不慢,但是如果資源多了,當然就很慢。圖片、css 、js 、html這些資源每個大概需要10-200ms ,一般都是30ms就ok了。不
Android開發中我們經常需要用到將dip、px相互換算、獲取手機屏幕的寬度、高度以及狀態欄高度等,如下是基於屏幕這一塊整理的一個類。package com.per.l