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()放入线程池中即可。

 

posted @ 2017-06-02 16:52  Sharley  阅读(6731)  评论(0编辑  收藏  举报