Handler的正確使用,使用靜態內部類+弱引用,解決記憶體洩漏,舉例說明在使用ProgressBar時的Handler類的靜態內部類實現。
在Android中使用ProgressBar進行回撥設定進度時候會提示‘This Handler class should be static or leaks might occur’的警告,那就說明是你的自定義Handler類有記憶體洩露的問題,一般來說就是持有外部類的引用。要解決這個ProgressBar的使用問題需要明確如下幾個知識點:
1.Android的UI(比如ProgressBar)也是執行緒不安全的,如果想要更新應用程式裡的UI元素,則必須在主執行緒中進行,否則會出現異常。
2.不能在UI主執行緒中使用Thread.sleep();會導致檢視變化看不到(後面做ProgressBar演示需要用到)。
3.靜態內部類是不持有外部類的引用,因此自定義Handler類可以用靜態內部類來完成,至於為什麼不持有外部類的引用可參考:
4.如果你想在靜態內部類/匿名類中使用外部類的屬性或方法時,可以顯示的持有一個弱引用(WeakReference )。
- 強引用:Java中裡面最廣泛的使用的一種,也是物件預設的引用型別,如果又一個物件具有強引用,那麼垃圾回收器是不會對它進行回收操作的,當記憶體的空間不足的時候,Java虛擬機器將會拋OutOfMemoryError錯誤,這時應用將會被終止執行
- 軟引用:一個物件如果只有一個軟引用,那麼當記憶體空間充足是,垃圾回收器不會對他進行回收操作,只有當記憶體空間不足的時候,這個物件才會被回收,軟引用可以用來實現記憶體敏感的快取記憶體,如果配合引用佇列(ReferenceQueue使用,當軟引用指向物件被垃圾回收器回收後,java會把這個軟引用加入到與之關聯的引用佇列中)
- 弱引用:弱引用是比軟引用更弱的一種的引用的型別,只有弱引用指向的物件的生命週期更短,當垃圾回收器掃描到只有具有弱引用的物件的時候,不敢當前空間是否不足,都會對弱引用物件進行回收,當然弱引用也可以和一個佇列配合著使用
- 引用佇列:ReferenceQueue一般是作為WeakReference SoftReference 的構造的函式引數傳入的,在WeakReference 或者是 softReference 的指向的物件被垃圾回收後,ReferenceQueue就是用來儲存這個已經被回收的Reference
下面給大家展示用靜態內部類實現Handler類來完成ProgressBar的進度條顯示的原始碼。
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private ProgressBar progressBar;
private MyHandler handler = new MyHandler(this);
/**
* 靜態內部類實現Handler
*/
private static class MyHandler extends Handler{
private WeakReference<MainActivity> mActivity;
private MyHandler(MainActivity mActivity) {
super();
this.mActivity = new WeakReference<MainActivity>(mActivity);
}
@Override
public void handleMessage(Message msg) {
if(mActivity.get() == null){
return;
}
//在靜態內部類/匿名類中使用外部類的屬性或方法時,可以顯示的持有一個弱引用
final MainActivity activity = mActivity.get(); //弱引用
activity.progress.setText(msg.arg1+"%");
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = findViewById(R.id.progress_bar); //例項化ProgressBar
Button button = findViewById(R.id.button);
button.setOnClickListener(this); //啟動進度條的按鈕新增點選事件
}
@Override
public void onClick(View view) {
if (view.getId() == R.id.button){
new Thread(new Runnable() {
@Override
public void run() {
int progress = progressBar.getProgress();
while (progress < 100) {
try {
Message message = new Message();
progress = progress + 1;
progressBar.setProgress(progress);
message.arg1 = progress;
handler.sendMessage(message);
Thread.sleep(100); //不能在主執行緒中使用
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
}
當然只是針對ProgressBar的顯示而又不想發生‘This Handler class should be static or leaks might occur’我們還可以使用Android提供的runOnUiThread來完成。原始碼如下:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private ProgressBar progressBar;
private int pro; //進度條的值
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = findViewById(R.id.progress_bar); //例項化ProgressBar
Button button = findViewById(R.id.button);
button.setOnClickListener(this); //啟動進度條的按鈕新增點選事件
}
@Override
public void onClick(View view) {
if (view.getId() == R.id.button){
pro = progressBar.getProgress();
new Thread(new Runnable() {
@Override
public void run() {
while (pro <= 100) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {//切換回主執行緒更改ProgressBar的值
@Override
public void run() {
progress.setText(String.format("%d%%", pro));
}
pro = pro + 1;
}
});
}
}
}).start();
}
}
}
小弟也是最近再跟著郭霖大牛的《第一行程式碼》在學習android,純純的菜鳥一枚,對很多東西的認識不深,知其然不知其所以然,這也是我的第一篇博文,寫的不好,有錯誤的地方希望各位大神包含和指正,小弟感激不盡!
相關推薦
Handler的正確使用,使用靜態內部類+弱引用,解決記憶體洩漏,舉例說明在使用ProgressBar時的Handler類的靜態內部類實現。
在Android中使用ProgressBar進行回撥設定進度時候會提示‘This Handler class should be static or leaks might occur’的警告,那就說明是你的自定義Handler類有記憶體洩露的問題,一般來說就是
WeakReference 在android中的應用 弱引用防止記憶體洩漏
首先我們來看一段程式碼 public classAutoActivityextendsActivity{ Handler handler = new Handler(){ publicvoidhandleMessage(android.os.Message msg)
分析ThreadLocal的弱引用與記憶體洩漏問題
目錄 一.介紹 二.問題提出 2.1記憶體原理圖 2.2幾個問題 三.回答問題 3.1為什麼會出現記憶體洩漏 3.2若Entry使用弱引用 3.3弱引用配合自動回收 四.總結 一.介紹 之前使用ThreadLocal的時候,就聽過Threa
匿名內部類持外部引用造成記憶體洩漏問題
public class SampleActivity extends Activity { private final Handler mLeakyHandler = new Handler() { @Override publi
Handler還需要用到弱引用(WeakReference)嗎?
網上很多文章都說寫Hanlder,需要用static宣告為靜態的,還需要用弱引用包裹建構函式傳來的Activity例項。 比如這篇英文部落格 http://www.androiddesignpatterns.com/2013/01/inner-class-handler-
[轉]Android 如何有效的解決記憶體洩漏的問題 Android 如何有效的解決記憶體洩漏的問題
Android 如何有效的解決記憶體洩漏的問題 前言:最近在研究Handler的知識,其中涉及到一個問題,如何避免Handler帶來的記憶體溢位問題。在網上找了很多資料,有很多都是互相抄的,沒有實際的作用。 本文的記憶體洩漏檢測工具是:LeakCanary &nbs
解決記憶體洩漏
一:寫p層的方法 //解耦 public void datach(){ if (shopView != null){ shopView = null; } } 二:主頁面的方法 @Override public void onDestroy() {
Android 如何有效的解決記憶體洩漏的問題
前言:最近在研究Handler的知識,其中涉及到一個問題,如何避免Handler帶來的記憶體溢位問題。在網上找了很多資料,有很多都是互相抄的,沒有實際的作用。 本文的記憶體洩漏檢測工具是:LeakCanary github地址:https://github.com/square/le
mvp銷燬,解決記憶體洩漏
mvp銷燬,解決記憶體洩漏 //model層銷燬執行緒 public void onDestory() { if (handler != null) { handler.removeCallbacksAndMessages(null); handler = null; } } //p
Android AsyncTask 取消全部任務 , 解決記憶體洩漏問題
以下程式碼具備的功能: 1. 取消當前新增的所有 AsyncTask , 儘量減少重複的網路請求任務 (場景: 我們需要在一個介面中定時每 10s 請求一次網路獲取一次資料 ,我們知道網路請求時間是不固定的 ,可能很快的請求完成,也可能很慢,因此,我為了儘量節省開銷
_064_Android_Android 如何有效的解決記憶體洩漏的問題
轉自https://www.cnblogs.com/zhaoyanjun/p/5981386.html,感謝作者的無私分享。 Android 如何有效的解決記憶體洩漏的問題 如何避免Handler帶來的記憶體溢位問題。 本文的記憶體洩漏檢測工具是:LeakCanary &nb
iOS NSString 記憶體洩漏 , 求解決
遞迴, autorelease物件如何避免記憶體洩漏???? -(NSString *) getStuJsonString : (StuNode *) stuNode{ NSString *nodeJsonString = [[NSString alloc] i
Jboss—java.lang.OutOfMemoryError:Metaspace (解決記憶體溢位,擴大記憶體)
講一講故事開頭吧,小菜自己覺得非常重要! 今天Jenkins構建專案後端成功,可怕的是到了伺服器上部署時就失敗了。開始拍錯,先是懷疑Jenkins在搗亂呢,因此在本地打包釋出,非常順利的成功了。把這個war包拿到伺服器上去部署,竟然失敗!排除Jenkins的嫌
教你如何解決沒有資質,讓金融貸款超市理財類APP也能快速上架!
還記得剛進入金融行業時,專案老大跟我說現在APP上架審的蠻嚴格,不管是安卓市場還是蘋果市場,之前產品一直沒有上架成功,你看下有沒有什麼辦法。之前一直從事的都是非金融行業,比如智慧硬體、物聯網或者線上教育,這些產品有些會涉及到直播問題,會相對遇到一定的阻力,其他的大多數情況下都是很容易上架的,基本
使用 Android Studio 檢測記憶體洩漏與解決記憶體洩漏問題
本文在騰訊技術推文上 修改 釋出。 http://wetest.qq.com/lab/view/63.html?from=ads_test2_qqtips&sessionUserType=BFT.PARAMS.195040.TASKID&ADUIN=913337456&a
使用C++11解決記憶體洩漏的問題
C++語言中沒有垃圾回收機制,必須自己去釋放分配的堆記憶體,否則就會記憶體洩漏。相信大部分C++開發人員都遇到過記憶體洩漏的問題,而查詢記憶體寫了的問題往往要花大量的精力。 解決這個問
webview api介紹+解決記憶體洩漏+js互動
1:建立webview 一般建立webview不採用在layout中直接去定義,而是用程式碼new一個webview出來,並且用RelativeLayout或LinearLayout做一個佔位. <LinearLayout android:id="@+id/wv_r
解決listview 中,點選item時,item裡的所有設定了selector的元件全部一起變色
listview中如果不設定,item裡面的每個元件的背景顏色的話,預設情況下,點選item時,會有listview的預設,點選變色。預設的效果很醜,所以我們一般都會使用自定義的顏色。 現在我要實現這種效果,如上圖紅框中的兩個元件。這是一個listview,我想要實現
Instruments Leak解決記憶體洩漏問題
iOS 5.0之後apple引入了Xcode編譯器特性ARC(Automatic Reference Counting,自動引用計數)來幫助開發者管理記憶體,但為了追求app的高效能與減少安裝包大小,工作中很多時候需要我們手動管理記憶體。再牛的開發者也不能保證自己寫的co
Android:Handler 二三事(二)由記憶體洩漏所想到的(垃圾回收機制)
主要內容解決Handler記憶體洩漏以及延伸(垃圾回收、引用等)解決Handler記憶體洩漏及延伸為什麼Handler會引起記憶體洩漏?這是一段使用Handler的程式碼public class Lea