上文说道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(); handler = new Handler(){@Override public void handleMessage(Message msg) {Log.e(TAG, "当前线程:" + Thread.currentThread()); }}; Looper.loop(); }}@Override protected void onCreate(Bundle savedInstanceState) {Create(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 flect.Method.invokeNative(Native Method)
at flect.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.Create(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 flect.Method.invokeNative(Native Method)
at flect.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) {Create(savedInstanceState); setContentView(R.layout.activity_main); HandlerThread ht = new HandlerThread("my HandlerThread"); ht.start(); handler = new Looper()){@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,
@Override public void run() {mTid = Tid(); Looper.prepare(); synchronized (this) {mLooper = Looper(); 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(); notifyAll(); }
法,继续往下走,所以,就保证了我们在创建
handler = new Looper()){时,不会出现空指针的情形。
我们可一同过HandlerThread很轻松就实现一部操作,此时我们的Handler是与HandlerThread这个子线程绑定的,所以这个handler的所发送的消息都将在这个子线程中进行处理
。所以此时我们就可一将一些耗时的操作放在这个Handler 的handleMessage(Message msg)方法中进行处理。
本文发布于:2024-01-31 00:53:01,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170663368924118.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |