日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java handler的用法_Handler和内部类的正确用法

發布時間:2024/9/27 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java handler的用法_Handler和内部类的正确用法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

PS:本文摘抄自《Android高級進階》,僅供學習使用

Android代碼中涉及線程間通信的地方經常會使用Handler,典型的代碼結構如下。

1

2

3

4

5

6

7

8

9

public?class?HandlerActivityextends?Activity{

//可能引入內存泄漏的用法

private?final?Handler mLeakyHandler =new?Handler(){

@Orrvide

public?void?handleMessage(Mesage msg){

//...

}

};

}

使用Android Lint分析這段代碼,會違反檢測項AndroidLintHandlerLeak,得到如下提示。

1

This Handlerclass?should bestatic?or leaks might occur.

那么產生內存泄漏的原因可能是什么呢?我們知道,Handler是和Looper以及MessageQueue一起工作的,在Android中,一個應用啟動后,系統默認會創建一個為主線程服務的Looper對象,該Looper對象用于處理主線程的所有Message對象,它的生命周期貫穿于整個應用的生命周期。在主線程中使用的Handler都會默認綁定到這個Looper對象。在主線程中創建Handler對象,它會立即關聯到主線程Looper對象的MessageQueue,這時發送到MessageQueue中的Message對象都會只有這個Handler對象的引用,這樣在Looper處理消息時常能回調到Handler的handlerMessage方法。因此,如果Message還沒有被處理完成,那么Handler對象也就不會被垃圾回收。

在上面的代碼中,將Handler的實例聲明為HandlerActivity類的內部類。而在Java語言中,非靜態內部匿名類會持有外部類的一個隱式的引用,這樣就可能會導致外部類無法被垃圾回收。因此,最終由于MessageQueue中Message還沒處理完成,就會持有Handler對象的引用,而非靜態的Handler對象會持有外部類HandlerActivity的引用,這個Activity無法被垃圾回收,從而導致內存泄漏。

一個明顯的會引入內存泄漏的例子如下。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

public?class?HandlerActivityextends?Activity{

//可能引入內存泄漏的用法

private?final?Handler mLeakyHandler =new?Handler(){

@Orrivide

public?void?handleMessage(Mesage msg){

//...

}

};

@Orrivide

protected?void?onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

//延遲5分鐘發送消息

mLeakyHandler.postDelayed(new?Runnable(){

@Orrivide

public?void?run(){/* ... */}

},1000*60*5);

}

}

由于消息延長5分鐘,因此,當用戶進入這個Activity并退出后,在消息發送并處理完成之前,這個Activity是不會被系統回收的(系統內存確實不夠使用的情況例外)。

如果解決呢。有兩個方案。

在子線程中使用Handler,這時需要開發者自己創建一個Looper對象,這個Looper對象的生命周期同一般的Java對象,因此這種用法沒有問題。

將Handler生命為靜態的內部類,前面說過,靜態內部類不會持有外部類的引用,英寸,野不會引起內存泄漏,經典用法的代碼如下。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

public?class?HandlerAcitivityextends?Activity{

//聲明一個靜態的Handler內部類,并持有外部類的弱引用

private?static?class?InnerHandlerextends?Handler{

private?final?WeakReference mActivity;

public?InnerHandler(HandlerAcitivity activity){

mActivity =new?WeakReference(activity);

}

public?void?handleMessage(Message msg){

HandlerAcitivity activity = mActivity.get();

if(activity!=null){

//...

}

}

}

private?final?InnerHandler mHandler =new?InnerHandler(this);

//靜態的匿名內部類不會持有外部類的引用

private?static?final?Runnable sRunnable =new?Runnable(){

@Override

public?void?run(){

//...

}

};

@Override

protected?void?onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

//延遲5分鐘發送消息

mHandler.postDelay(sRunnable,1000*60*5);

}

}

總結

以上是生活随笔為你收集整理的java handler的用法_Handler和内部类的正确用法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。