Thread,Runnable,Handler,Handler.Callback,Looper,MessageQueue,HandlerThread
新线程的开启:
①new Thread(new Runnable() { @Override public void run(){ //异步执行 }}).start();②class MyThread extends Thread { @Override public void run(){ //异步执行 }}new MyThread().start();③class MyRunnable implements Runnable { @Overrid public void run(){ //异步执行 }}new Thread(new MyRunnable()).start();Runnable:
按抠脚的英语理解的是,Runnable接口被实现后,必须要用Thread类开启线程,Runnable的设计理念是提供一个公共的方法执行内容。Runnable不一定要用new Thread()的方法来实例化Runnable,也可以用继承Thread来重写run()方法。
Handler
①class MyThread extends Thread { PRivate Handler myHandler; @Override public void run() { Looper.prepare();//要在线程中实例化Handler,就必须调用该方法 myHandler = new Handler(); //异步执行 //在最后还要执行Looper.loop();不然消息是不会发送到消息队列中的 myHandler.post(new Runnbale() { @Overrid public void run(){ //属于异步线程 } }); }}②Handler handler = new Handler(){...};class MyThread = new Thread(){...}这时候其实挺疑惑为什么在Thread中一定要调用Looper.prepare();可以先看下构造函数,然后看看源码。 Handler.Callback是可以重写Handler类中的handlerMessage()方法。 可知道只要是不传Looper对象的构造参数,
最终都是走到以下这个方法:
在这行中mLooper = Looper.myLooper()中,可以看到看到,当mLooper==null的时候,会报当前线程没有调用Looper.prepare(),而在Looper.prepare,Looper.prepare()中看下面:
public static @Nullable Looper myLooper() { return sThreadLocal.get(); // 获取线程Looper}public static void prepare() { prepare(true); }private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); // prepare是会实例化一个新的Looper }从以上就知道为什么要调用Looper.prepare()了。而在Activity中的实例化Handler却不需要的原因的是在ActivityThread中已经调用了Looper.prepareMainLooper(); 所以这里要注意的地方就是,在Thread中实例化的Handler是不能修改UI线程了。因为它的消息队列被异步线程的Looper轮询了,而不是MainLooper轮询的。
HandlerThread:
HandlerThread handlerThread = new HandlerThread("myHandlerThread");handlerThread.start();Handler asyncHandler = new Handler(handlerThread.getLooper());Handler uiHandler = new Handler();asyncHandler.post(new Runnable(){ @Override public void run(){ // 异步 uiHandler.post(new Runnbale(){ // ui线程 }) }});/*HandlerThread开启的线程后。声明asyncHandler的时候将HandlerThread的Looper赋给asyncHandler,那么asyncHandler post的就是一个异步的的Runnable.而uiHandler没有的到HandlerLooper,所以是MainActivity的Looper,属于Ui线程。*/②Handler uiHandler = new Handler() { @Override public void handleMessage() {...}}asyncHandler.post(new Runnable(){ @Override public void run(){ // 异步 uiHandler.sendMessage(...); }});Android提供的在其它线程操作UI线程的方法:
①Activity.runOnUiThread(Runnable)②View.post(Runnable)③View.postDelayed(Runnable, long)相关查阅资料: http://blog.csdn.net/guolin_blog/article/details/9991569 https://developer.android.com/reference/android/os/Handler.html https://developer.android.com/reference/java/lang/Runnable.html https://developer.android.com/reference/java/lang/Thread.html https://developer.android.com/reference/android/os/Looper.html 在其它线程访问UI线程: https://developer.android.com/guide/components/processes-and-threads.html https://developer.android.com/training/multiple-threads/communicate-ui.html#Handler
新闻热点
疑难解答