zoukankan      html  css  js  c++  java
  • 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()放入线程池中即可。

  • 相关阅读:
    利用qt打开一张图片并转成灰度矩阵
    适配手机端浏览器
    ps常用快捷键(供自己学习查看)
    用选框工具画圆角矩形
    ps制作有背景图片的字体
    所有iOS 设备的屏幕尺寸
    九宫格有规律高亮滚动效果
    移动端点击事件全攻略
    移动端ios升级到11及以上时,手机弹框输入光标出现错位问题
    linux下截取整个网页
  • 原文地址:https://www.cnblogs.com/Sharley/p/6934121.html
Copyright © 2011-2022 走看看