国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Activity已銷毀,創建的線程未回收問題

2019-11-09 14:08:15
字體:
來源:轉載
供稿:網友

今天在做新模塊測試時發現了一個嚴重的問題,當一個activity開啟一個線程時,如果當前activity調用finish()函數不會關閉當前創建的線程。對于每個新建activity,如果activity中的線程發生內存泄漏。在java中線程時垃圾回收機制的根源,也就是說,在運行系統中DVM虛擬機總會使硬件持有運行狀態的進程的引用,結果導致處于運行狀態的線程將永遠不會回收。因此你必須為你的后臺線程實現銷毀邏輯。

先說下問題出現的場景,我在一個activity中創建一個線程,輪詢去發送請求,正常情況下是沒什么問題的,先看下問題代碼:

@OverridePRotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    new Thread(new Runnable() {        @Override        public void run() {            while (1 == 1) {                try {                    Thread.sleep(1000);                    Log.i("-------", "running");                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    }).start();}這時看Log日志是正常打印,然后我按返回鍵退出當前應用,發現Log日志還在打印,問題出現了,線程被沒有被回收,而且當你再次返回到應用時,會再在后臺創建一個線程,兩個線程同時在跑。

在Java中強制關閉線程是非安全性操作,這時我們要為自己的線程添加判斷條件,相關代碼如下:

private MyThread myThread;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    myThread = new MyThread();    myThread.start();}private class MyThread extends Thread {    private boolean stop = false;    @Override    public void run() {        super.run();        while (!stop) {            try {                Thread.sleep(1000);                Log.i("-------", "running");            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    public void close() {        stop = true;    }}@Overrideprotected void onDestroy() {    super.onDestroy();    myThread.close();}這樣,當activity銷毀時走destroy函數然后調用Thread的close,讓線程退出輪詢,保證了線程安全回收。

還有另外一個思路來讓線程可以及時回收,我們知道context對象與activity是綁定的,我們可以實例application來暫存當前context與當前context進行比較,我們可以優化上面的代碼,具體代碼如下:

自定義application用來暫存context對象:

public class MyApplication extends Application {    static Context appContext;    @Override    public void onCreate() {        super.onCreate();    }    public static void setContext(Context context) {        appContext = context;    }}讓線程去做context比較,這樣我們就可以忽略activity的生命周期:

private MyThread myThread;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    MyApplication.setContext(this);    myThread = new MyThread(this);    myThread.start();}private class MyThread extends Thread {    private boolean stop = false;    private Context context;    public MyThread(Context context) {        this.context = context;    }    @Override    public void run() {        super.run();        while (context == MyApplication.appContext) {            try {                Thread.sleep(1000);                Log.i("-------", "running");            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}

大功告成。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 五大连池市| 嘉荫县| 三亚市| 桦甸市| 宿迁市| 临泉县| 翁源县| 宁晋县| 通榆县| 乐陵市| 秭归县| 商丘市| 新昌县| 霍林郭勒市| 石首市| 高州市| 嘉定区| 固原市| 平果县| 桐柏县| 双桥区| 龙江县| 霞浦县| 定日县| 平陆县| 罗山县| 浠水县| 祁东县| 从化市| 额济纳旗| 勐海县| 分宜县| 满洲里市| 鄂州市| 海南省| 楚雄市| 左云县| 玉溪市| 香河县| 曲靖市| 迁安市|