Android HandlerThread和IntentService用法和源码解析
来源:互联网 发布:儿童编程先学什么 编辑:程序博客网 时间:2024/06/11 17:46
HandlerThread
用法
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d("LiaBin", "MainActivity onCreate tid:" + Thread.currentThread().getId()); HandlerThread handlerThread = new HandlerThread("handler-thread"); handlerThread.start(); Handler handler = new Handler(handlerThread.getLooper()) { @Override public void handleMessage(Message msg) { Log.d("LiaBin", "MainActivity handler tid:" + Thread.currentThread().getId()); try { Thread.sleep(20000);//dosomething....//handlerThread.quit(); } catch (InterruptedException e) { e.printStackTrace(); } } }; handler.sendEmptyMessage(0); }}
HandlerThread显而易见的好处就是不用额外自定义Thread了,同时可以通过getLooper方法获取HandlerThread线程对应的looper,
所以handler的发送消息就发送到子线程looper对应的消息队列中去了,所以此时可以用该handler来让main线程给子线程发送消息了
此时如果打开DDMS查看这个进程,那么就会发现"handler-thread"这个线程一直存在,如果耗时操作执行完后,不做任何处理,
还是挺占用系统资源的,所以耗时操作执行完后可以执行handlerThread.quit();那么HandlerThread这个线程就会进入死亡态,不再占用系统资源
因为HandlerThread的run方法里面,最后调用的是Looper.loop(); 这是一个死循环,一直不断的取MessageQueue中的消息,所以该HandlerThread线程一直都在。
源码解析
public class HandlerThread extends Thread { …… @Override public void run() { mTid = Process.myTid(); Looper.prepare(); //为该线程绑定looper synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); //一直开始循环取looper对应队列中的消息,所以如果不手动quit,该线程就一直存在 mTid = -1; } //可以获取该线程对应的looper,构造handler的时候使用这个参数,handler中处理消息就会放在该子线程中,而不是main线程 public Looper getLooper() { if (!isAlive()) { return null; } // If the thread has been started, wait until the looper has been created. synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; } //手动终止looper循环,耗时操作执行完,调用该方法可以使Looper停止不停的loop消息,从而run方法可以执行完,从而该线程终止,否则run方法一直在运行,该线程也一直在运行态 public boolean quit() { Looper looper = getLooper(); if (looper != null) { looper.quit(); return true; } return false; }……}
说明:
1. 线程只有run()方法执行完,才会终止,同时进入死亡态,looper没有终止那么run就一直在运行
IntentService
用法
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d("LiaBin", "MainActivity onCreate tid:" + Thread.currentThread().getId() + " tname:" + Thread.currentThread().getName()); startService(new Intent(this, MyIntentService.class)); }}public class MyIntentService extends IntentService { public MyIntentService() { super("MyIntentService"); } @Override public void onCreate() { super.onCreate(); Log.d("LiaBin", "MyIntentService onCreate tid:" + Thread.currentThread().getId() + " tname:" + Thread.currentThread().getName()); } @Override protected void onHandleIntent(Intent intent) { Log.d("LiaBin", "MyIntentService onHandleIntent tid:" + Thread.currentThread().getId() + " tname:" + Thread.currentThread().getName()); try { Thread.sleep(5000); //dosomething.... } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void onDestroy() { super.onDestroy(); Log.d("LiaBin", "MyService onDestroy"); }}此时耗时的操作可以放在onHandleIntent中,因为onHandleIntent是在HandlerThread子线程中被调用,不会阻塞main线程。IntentService的优点显而易见
不用在service中手动开启线程,同时耗时操作执行完后,IntentService服务自动终止,并不会一直停留在后台。同时内部开启的HandlerThread子线程也终止
IntentService的onDestroy方法中有
@Override public void onDestroy() { mServiceLooper.quit(); }mServiceLooper.quit();//导致线程终止
可以看到此时打印:
10-26 13:47:05.170 20397-20397/? D/LiaBin: MainActivity onCreate tid:1 tname:main
10-26 13:47:05.193 20397-20397/? D/LiaBin: MyIntentService onCreate tid:1 tname:main
10-26 13:47:05.194 20397-20429/? D/LiaBin: MyIntentService onHandleIntent tid:8233 tname:IntentService[MyIntentService]
源码解析
注意
1. IntentService继承自service,所以具有service的特性,每个服务都只会存在一个实例,只有第一次startService的时候才会调用onCreate,否则onStart
2. onHandleIntent在子线程中执行,所以不会阻塞main线程,耗时操作可以放在这里。同时onHandleIntent执行完后该service销毁调用onDestroy方法,onDestroy方法通知会导致子线程不再looper,子线程终止。从DDMS中也可以看到MyIntentService线程执行完耗时操作就终止
3. service还是运行在main线程中的,可以从onCreate,onStart方法中打印的还是main线程可以看出。
private volatile Looper mServiceLooper; private volatile ServiceHandler mServiceHandler; private String mName; private boolean mRedelivery; private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { onHandleIntent((Intent)msg.obj); stopSelf(msg.arg1); } }}
onHandleIntent在handleMessage中执行,所以执行在HandlerThread子线程中
stopSelf(msg.arg1); onHandleIntent执行完后,就会停止该service,进而调用该Service的onDestroy方法,进而mServiceLooper.quit();那么就会终止HandlerThread子线程
@Override public void onDestroy() { mServiceLooper.quit(); }内部onCreate中创建了一个子线程,使用HandlerThread实现mServiceHandler使用该子线程的looper,所以handler是在该子线程中处理消息的。注意该service还是运行在main线程中的
@Override public void onCreate() { // TODO: It would be nice to have an option to hold a partial wakelock // during processing, and to have a static startService(Context, Intent) // method that would launch the service & hand off a wakelock. super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); }
onStart方法中使用handler发送消息到HandlerThread子线程
@Override public void onStart(Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); } /** * You should not override this method for your IntentService. Instead, * override {@link #onHandleIntent}, which the system calls when the IntentService * receives a start request. * @see android.app.Service#onStartCommand */ @Override public int onStartCommand(Intent intent, int flags, int startId) { onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; }
0 0
- Android HandlerThread和IntentService用法和源码解析
- 【Android】IntentService & HandlerThread源码解析
- 【Android】IntentService & HandlerThread源码解析
- Android中的HandlerThread和IntentService
- IntentService与HandlerThread源码解析
- Android开发之IntentService和HandlerThread分析
- Android中HandlerThread和IntentService详解
- Android中IntentService和HandlerThread的分析
- HandlerThread使用和源码解析
- Handler与HandlerThread、IntentService源码解析
- IntentService源码分析以及HandlerThread的用法
- Android多线程-HandlerThread用法与源码解析
- Android 的线程(AsyncTask、HandlerThread、IntentService详解)和线程池
- Android 的线程(AsyncTask、HandlerThread、IntentService详解)和线程池
- Android中线程形态AsyncTask、HandlerThread 和 IntentService简介
- android IntentService Service HandlerThread 源码解读
- android HandlerThread源码解析
- Android IntentService 源码解析
- Codeforces Round #327 (Div. 2) (A. Wizards' Duel 简单数学)
- jquery判断checked的三种方法:
- R语言学习资料大搜刮
- javaScript & jquery判断图片是否加载完毕
- 主Moudle的minSdkVersion小于LibMoudle的minSdkVersion解决
- Android HandlerThread和IntentService用法和源码解析
- 图像镜像之水平镜像
- 服务器端数据合法性验证:签名sign和口令token原理
- JavaScript入门(上篇)
- 在digitalocean droplet上安装博客平台ghost
- Caused by: org.hibernate.MappingException: No Dialect mapping for JDBC type: -4
- ubuntu下安装matlab2014b
- awesome-machine-learning
- Windows平台下SVN安装配置及使用