摘要:

  在Android开发中经常会使用到线程,一想到线程,很多同学就立即使用new Thread(){...}.start()这样的方式。这样如果在一个Activity中多次调用上面的代码,那么将创建多个匿名线程,程序运行的越久可能会越来越慢。因此,需要一个Handler来启动一个线程,以及删除一个线程,保证线程不会重复的创建。

正文:

1、创建Handler的一般方式

一般会使用Handler handler = new Handler(){...}创建。
这样创建的handler是在主线程即UI线程下的Handler,即这个Handler是与UI线程下的默认Looper绑定的。
Looper是用于实现消息队列和消息循环机制的。
因此,如果是默认创建Handler那么如果线程是做一些耗时操作如网络获取数据等操作,这样创建Handler是不行的。

2、使用HandlerThread 

HandlerThread实际上就一个Thread,只不过它比普通的Thread多了一个Looper。
我们可以使用下面的例子创建Handler :

HandlerThread thread = new HandlerThread("MyHandlerThread");
thread.start();
mHandler = new Handler(thread.getLooper());
mHandler.post(mBackgroundRunnable);

创建HandlerThread时要把它启动了,即调用start()方法。
然后创建Handler时将HandlerThread中的looper对象传入。
那么这个mHandler对象就是与HandlerThread这个线程绑定了(这时就不再是与UI线程绑定了,这样它处理耗时操作将不会阻塞UI)。
最后把实现耗时操作的线程post到mHandler的消息队列里面。
注意的是,mBackgroundRunnable这个线程并没有启动,因为没有调用start()方法。

完整demo:

public class MainActivity extends Activity implements OnClickListener{
public static final String TAG = "MainActivity";
private Handler mHandler;
private boolean mRunning = false;
private Button mBtn; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); HandlerThread thread = new HandlerThread("MyHandlerThread");
thread.start();//创建一个HandlerThread并启动它
mHandler = new Handler(thread.getLooper());//使用HandlerThread的looper对象创建Handler,如果使用默认的构造方法,很有可能阻塞UI线程
mHandler.post(mBackgroundRunnable);//将线程post到Handler中 mBtn = (Button)findViewById(R.id.button);
mBtn.setOnClickListener(this);
} @Override
protected void onResume() {
super.onResume();
mRunning = true;
} @Override
protected void onStop() {
super.onStop();
mRunning = false;
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} //实现耗时操作的线程
Runnable mBackgroundRunnable = new Runnable() { @Override
public void run() {
//----------模拟耗时的操作,开始---------------
while(mRunning){
Log.i(TAG, "thread running!");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//----------模拟耗时的操作,结束---------------
}
}; @Override
protected void onDestroy() {
super.onDestroy();
//销毁线程
mHandler.removeCallbacks(mBackgroundRunnable);
} @Override
public void onClick(View v) {
Toast.makeText(getApplication(), "click the button!!!", Toast.LENGTH_SHORT).show();
}
}

如果在onCreate()方法中里面没有使用HandlerThread而是在直接使用Handler的默认构造方法来创建Handler,那么mBackgroundRunnable将会阻塞UI线程。

 3、线程销毁 

用上面的方式来创建线程,在销毁时就可以使用

mHandler.removeCallbacks(mBackgroundRunnable); 

销毁一个线程,这样就可以避免在多次进入同一个Activity时创建多个同时运行着的线程。

原文:

Android线程的创建与销毁[2014-07-11](2013-06-19).http://www.bdqn.cn/news/201306/9538.shtml

Android线程的创建与销毁的更多相关文章

  1. 从微信推送看Android Service的创建和销毁

    启动服务是有两组参数影响服务的状态. 1.在onStartCommand(Intent intent, int flags, int startId) 接口中返回值,例如 START_STICKY;  ...

  2. APUE学习之多线程编程(一):线程的创建和销毁

    一.线程标识      和每个进程都有一个进程ID一样,每个线程也有一个线程ID,线程ID是以pthread_t数据类型来表示的,在Linux中,用无符号长整型表示pthread_t,Solaris ...

  3. 理解Android线程创建流程

    copy from : http://gityuan.com/2016/09/24/android-thread/ 基于Android 6.0源码剖析,分析Android线程的创建过程 /androi ...

  4. Android(java)学习笔记267:Android线程池形态

    1. 线程池简介  多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.     假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...

  5. android线程与线程池-----线程池(二)《android开发艺术与探索》

    android 中的线程池 线程池的优点: 1 重用线程池中的线程,避免了线程的创建和销毁带来的性能开销 2 能有效的控制最大并发数,避免大量线程之间因为喜欢抢资源而导致阻塞 3 能够对线程进行简单的 ...

  6. android 线程那点事

    在操作系统中,线程是操作系统调度的最小单元,同时线程又是一种受限的系统资源,即线程不可能无限制的产生,并且线程的创建和销毁都会有相应的开销,当系统中存在大量的线程时,系统会通过时间片轮转的方式调度每个 ...

  7. Android(java)学习笔记211:Android线程池形态

    1. 线程池简介  多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.     假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...

  8. android线程及线程池

    众所周知,在UI系统中进行一些耗时操作,都会导致卡顿现象,因为一次刷新在16ms,如果当次操作过了这个时间,那么用户就能感觉到明显的卡顿,甚至引起ANR . 对于这种情况,一般都是再起一个线程,进行一 ...

  9. java/android线程池详解

    一,简述线程池: 线程池是如何工作的:一系列任务出现后,根据自己的线程池安排任务进行. 如图: 线程池的好处: 重用线程池中的线程,避免因为线程的创建和销毁所带来的性能开销. 能有效控制线程池的最大并 ...

随机推荐

  1. 树莓派进阶之路 (027) - 在Linux中增加swap空间

    原贴地址:http://blog.csdn.net/chinalinuxzend/article/details/1759593  在Linux中增加swap空间 在安装Linux的时候,不知道swa ...

  2. Linux下出现command not found的解决办法

    不管是普通用户还是ROOT用户,修改~/.bash_profile文件,在文件最后加上:export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/u ...

  3. k8s官方安装版本

    一.概述 官方安装链接:https://kubernetes.io/docs/getting-started-guides/kubeadm/ 之前使用是yum直接安装组件,现由kubeadm来自动安装 ...

  4. VM页面中遍历枚举类

    1)自定义的枚举类如下所示: public enum BusType { MID_SMALL(1, "中小件"), FRESH(2, "生鲜"), GLOBAL ...

  5. Linux中断 - 综述

    一.前言 一个合格的linux驱动工程师需要对kernel中的中断子系统有深刻的理解,只有这样,在写具体driver的时候才能: 1.正确的使用linux kernel提供的的API,例如最著名的re ...

  6. linux下配置tomcat集群的负载均衡

    linux下配置tomcat集群的负载均衡 一.首先了解下与集群相关的几个概念集群:集群是一组协同工作的服务实体,用以提供比单一服务实体更具扩展性与可用性的服务平台.在客户端看来,一个集群就象是一个服 ...

  7. python .dcm文件读取,并转化为.jpg格式

    .dcm文件是DICOM(Digital Imaging and Communications in Medicine)即医学数字成像和通信中记录医学图像和相关信息的文件,在用于医学图像处理的时候我们 ...

  8. Hadoop创建/删除文件夹出错

    log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFact ...

  9. java.lang.RuntimeException: Date pattern must be set for column update_time in the schema of component

    使用Talend open studio  ,从mysql数据源中读取数据,将数据导出到excel文档,另外一个mysql数据库,和一个普通文件,遇到标题的错误,模型如下图所示: tMap将30.7中 ...

  10. haproxy+keepalived配置haproxy反向代理的高可用

    http://www.cnblogs.com/shantu/p/4586277.html