最近在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()放入線程池中即可。