Handler(原理) HandlerThread 轻松实现异步功能
来源:互联网 发布:网络平台投稿 编辑:程序博客网 时间:2024/06/05 17:08
上文说道Handler可以与任意线程绑定,这点可以帮助我们很轻松就是想异步工能
见如下代码,
public class MainActivity extends Activity { private static final String TAG = "Handler_demo"; private Handler myHandler; class MyThread extends Thread { public Handler handler ; public Looper looper; public void run(){ Looper.prepare(); looper = Looper.myLooper(); handler = new Handler(){ @Override public void handleMessage(Message msg) { Log.e(TAG, "当前线程:" + Thread.currentThread()); } }; Looper.loop(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MyThread mt = new MyThread(); mt.start(); myHandler = new Handler(mt.looper){ @Override public void handleMessage(Message msg) { Log.e(TAG, "Run IN 线程:" + Thread.currentThread()); } }; myHandler.sendEmptyMessage(0); }}
运行后发现包以下异常
09-27 22:41:50.577 1608-1608/com.liaoli.handleexample E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.liaoli.handleexample/com.liaoli.handleexample.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.liaoli.handleexample.MainActivity.onCreate(MainActivity.java:52)
at android.app.Activity.performCreate(Activity.java:5133)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
报异常的为
myHandler = new Handler(mt.looper){这一行,也就是mt.looper为空了,这说明子线成还未来得及创建Looper实例,
此时取出来的肯定为空啊,针对这种情况,android为我们提供了一种解决方案,
提供了一个类,
public class HandlerThread extends Thread
他是一个线程类,下面看一个简单的例子:
package com.liaoli.handlerthread_demo;import android.app.Activity;import android.os.Handler;import android.os.HandlerThread;import android.os.Message;import android.os.Bundle;import android.util.Log;public class MainActivity extends Activity { private static final String TAG = "MainActivity"; private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); HandlerThread ht = new HandlerThread("my HandlerThread"); ht.start(); handler = new Handler(ht.getLooper()){ @Override public void handleMessage(Message msg) { Log.e(TAG, "Run IN 线程:" + Thread.currentThread()); } }; handler.sendEmptyMessage(0); }}运行后打印:
09-27 23:07:09.237 11939-11956/com.liaoli.handlerthread_demo E/MainActivity﹕ Run IN 线程:Thread[my HandlerThread,5,main]
my HandlerThread 是我们给这个HandlerThread线程的名字,这个HandlerThread的run 方法中会去创建一个与此线程绑定的Looper,
@Overridepublic void run() { mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); mTid = -1;}
此时并没有报空指针,那么,他是怎么做到的呢?我们看HandlerThread的
/** * This method returns the Looper associated with this thread. If this thread not been started * or for any reason is isAlive() returns false, this method will return null. If this thread * has been started, this method will block until the looper has been initialized. * @return The looper. */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;}方法,他首先会取判断线程自己是不是活的,然后判断mLooper是否为null ,如果为空就wait(),也就是说为空就不会往下走了,器run方法中当mLooper 创建后,会取唤醒这个方
synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); }
法,继续往下走,所以,就保证了我们在创建
handler = new Handler(ht.getLooper()){时,不会出现空指针的情形。
我们可一同过HandlerThread很轻松就实现一部操作,此时我们的Handler是与HandlerThread这个子线程绑定的,所以这个handler的所发送的消息都将在这个子线程中进行处理
。所以此时我们就可一将一些耗时的操作放在这个Handler 的handleMessage(Message msg)方法中进行处理。
- Handler(原理) HandlerThread 轻松实现异步功能
- Android:用Handler实现异步处理功能
- Android:用Handler实现异步处理功能
- Android:用Handler实现异步处理功能
- Android:用Handler实现异步处理功能
- Android:用Handler实现异步处理功能
- Android:用Handler实现异步处理功能
- Android:用Handler实现异步处理功能
- Android:用Handler实现异步处理功能
- Android:用Handler实现异步处理功能
- Android:用Handler实现异步处理功能
- Android:用Handler实现异步处理功能
- Android开发中的Handler线程初窥,及HandlerThread异步通信的实现。
- Android开发中的Handler线程初窥,及HandlerThread异步通信的实现
- Android开发中的Handler线程初窥,及HandlerThread异步通信的实现
- Android开发中的Handler线程初窥,及HandlerThread异步通信的实现
- Android开发中的Handler线程初窥,及HandlerThread异步通信的实现。
- Handler&HandlerThread
- impress.js
- angularjs中的使用注意
- 瀑布流
- Contains Duplicate III
- ios9 提交ipad出现bundle错误的解决方案
- Handler(原理) HandlerThread 轻松实现异步功能
- Android 5.1 Contacts源码分析(二):Contacts模块主要窗口
- Reverse Words in a String
- SearchView+RecyclerView+GreenDao的搜索功能实现(1)
- svn代码回滚和合并的利器svn merge
- redmine 和 github 集成
- C++ STL学习
- 六种方式实现hibernate查询
- struts2-validate内置校验器失效的解决方法