android 避免線程的重復創建(HandlerThread、線程池)


最近在android開發中,用到都是new Thread(){...}.start()這種方式。本來這樣是可以,但是最近突然爆出Performing stop of activity that is not resumed 錯誤,google了一下發現是線程多次創建的問題;

 

多次使用上面的方式,會創建多個匿名線程。使得程序運行起來越來越慢。

因此,可以考慮使用一個Handler來啟動一個線程,當該線程不再使用就刪除,保證線程不會重復創建。
一般會使用Handler handler = new Handler(){...}創建Handler。這樣創建的handler是在主線程即UI線程下的Handler,
即這個Handler是與UI線程下的默認Looper綁定的。Looper是用於實現消息隊列和消息循環機制的。
因此,如果是默認創建Handler那么如果線程是做一些耗時操作如網絡獲取數據等操作,這樣創建Handler是不行的。
Android API提供了HandlerThread來創建線程。官網的解釋是:Handy class for starting a new thread that has a looper.
The looper can then be used to create handler classes. Note that start() must still be called.
HandlerThread實際上就一個Thread,只不過它比普通的Thread多了一個Looper。
創建HandlerThread時要把它啟動了,即調用start()方法。然后創建Handler時將HandlerThread中的looper對象傳入。

 

代碼如下

HandlerThread thread = new HandlerThread("MyHandlerThread");  
thread.start();  
mHandler = new Handler(thread.getLooper());  
mHandler.post(new Runnable(){...});  
 

 

完整代碼(需要在調用線程的Activity 在銷毀時 移除線程)

 1 public class MainActivity extends Activity implements OnClickListener{  
 2 private Handler mHandler;  
 3 private HandlerThread mHandlerThread;  
 4 private boolean mRunning;  
 5 private Button btn;  
 6 @Override  
 7 protected void onDestroy() {  
 8     mRunning = false;  
 9     mHandler.removeCallbacks(mRunnable);  
10     super.onDestroy();  
11 }  
12 @Override  
13 protected void onResume() {  
14     mRunning = true;  
15     super.onResume();  
16 }  
17 @Override  
18 protected void onStop() {  
19     mRunning = false;  
20     super.onStop();  
21 }  
22 @Override  
23 protected void onCreate(Bundle savedInstanceState) {  
24     super.onCreate(savedInstanceState);  
25     setContentView(R.layout.activity_main);  
26     btn = (Button) findViewById(R.id.btn);  
27     btn.setOnClickListener(this);  
28     mHandlerThread = new HandlerThread("Test", 5);  
29     mHandlerThread.start();  
30     mHandler = new Handler(mHandlerThread.getLooper());  
31 }  
32 private Runnable mRunnable = new Runnable() {  
33     @Override  
34     public void run() {  
35         while (mRunning) {  
36             Log.d("MainActivity", "test HandlerThread...");  
37             try {  
38                 Thread.sleep(200);  
39             } catch (Exception e) {  
40                 e.printStackTrace();  
41             }  
42         }  
43     }  
44 };  
45 @Override  
46 public void onClick(View v) {  
47     switch(v.getId()) {  
48     case R.id.btn :  
49         mHandler.post(mRunnable);  
50         break;  
51     default :  
52         break;  
53     }  
54 }  
55 }  

 轉自:http://blog.csdn.net/a_tao123/article/details/41279019

 

/***************************************************************************************************************************************************************************/

然而最后我發現還是線程池更好用。。。

ExecutorService mExecutorService;
mExecutorService.submit(new Runnable() {
            @Override
            public void run() {
                //需要操作的代碼
            }
        });

將每次需要提交的線程都用mExecutorService.submit()放入線程池中即可。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM