国产探花免费观看_亚洲丰满少妇自慰呻吟_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();            }        }    }}

大功告成。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 扶沟县| 民权县| 昌邑市| 万源市| 衡阳县| 右玉县| 新河县| 文登市| 武胜县| 新兴县| 峨眉山市| 潍坊市| 金湖县| 东乡族自治县| 通州市| 高碑店市| 山西省| 永新县| 商都县| 仁化县| 嘉义县| 五常市| 固始县| 太白县| 清苑县| 石柱| 霸州市| 磴口县| 环江| 金川县| 永城市| 南皮县| 鹤峰县| 沿河| 南安市| 日照市| 永丰县| 沙洋县| 佛教| 公主岭市| 建湖县|