-
使用handler时遇到的问题查看全部
-
Handler查看全部
-
handler是android给我们提供用来更新UI的一套机制,也会死一套消息处理的机制,我们可以发送消息,也可以通过他处理消息查看全部
-
handler查看全部
-
handler:1、用于更新UI;2、是一套消息处理机制查看全部
-
/** * 与子线程相关的Handler */ public class MyThread extends Thread { public Handler handler; @Override public void run() { Looper.prepare();//消息队列准备 handler = new Handler() { @Override public void handleMessage(Message msg) { System.out.println("currentThread:" + Thread.currentThread()); } }; Looper.loop();//循环处理消息 } }查看全部
-
程序运行-->ActivityThread.main()--[ Looper.prepareMainLooper() ] --[ prepare(boolean guitAllowed) ] -- [ threadLocal.set(new Looper(quitAllowed)) ] --[ new MessageQueue(quitAllowed) ]查看全部
-
1.不能直接在非UI线程直接更新UI(大多数时候)。<br> 2.每次创建Handler时需要给它绑定一个looper,如果是主线程不给定具体的looper则会绑定默认的looper。<br> 3.子线程运行时一定要调用start()方法。<br> 4.在某些特殊情况下在非UI线程是可以更新UI的//不推荐使用(当刚启动Activity即onCreate里面此时onResume方法还没有执行的时候可以,因为在线程中更新UI时会调用ViewParent.invalidateChild()方法检查当前的Thread是否是UIThread,若为UIThread则可以更新(ViewParent是一个接口类,其实现是ViewRootImpl;invalidateChild()方法调用checkThread()方法来检查线程是否为主线程)。ViewRootImp是在onResume方法中初始化的,所以只要在ViewRootImpl创建之前更新UI(在onCreate方法中创建线程并执行,此时还没有初始化ViewRootImp),就可以逃避掉checkThread()的检查进而更新UI。)查看全部
-
非UI线程能否更新UI --->刚启动的时候,立即在非UI线程更新->不报错。 --->休眠2s钟以后,更新——————>报错 更新UI-->会调用checkForRelayout()方法 -->invalidate()方法-->invalidate(true)方法,关注viewParent-->ViewRootImpl是ViewParent的实现类 --->p.invalidateChild()-->查看ViewRootImpl.invalidateChild()-->checkThread()方法-->判断UI线程是否是当前线程,不想等抛出异常。 ViewRootImpl是onResume()方法才会创建。所以onCreate()方法中要延迟才可以。 handleResumeActivity()方法---》viewManager.addView()-->ViewRootImpl初始化。,关注viewParent-->ViewRootImpl是ViewParent的实现类查看全部
-
在非UI线程中是可以更新Ui的(在onCreate中创建新线程更新UI): 当刚启动Activity即onCreate里面此时onResume方法还没有执行的时候可以,因为在线程中更新UI时会调用ViewParent.invalidateChild()方法检查当前的Thread是否是UIThread,若为UIThread则可以更新(ViewParent是一个接口类,其实现是ViewRootImpl;invalidateChild()方法调用checkThread()方法来检查线程是否为主线程)。ViewRootImp是在onResume方法中初始化的,所以只要在ViewRootImpl创建之前更新UI(在onCreate方法中创建线程并执行,此时还没有初始化ViewRootImp),就可以逃避掉checkThread()的检查进而更新UI。查看全部
-
更新UI的4种方式(其实内部都是handler机制): 1.通过Handler的post方法(); 2.调用Handler.sendMessage()或Handler.sendEmptyMessage()方法,传统的方法 3.重写Activity中的runOnUIThread方法更新; 4.调用View自身的post(Runnable run)方法更新;查看全部
-
主线程和子线程之间如何相互通信: 1. 子线程向主线程发送消息,是通过调用主线程的Handler,发送信息给主线程的Looper,该Hnadler绑定了主线程的Looper。 2. 主线程向子线程发送消息,是通过调用子线程的Handler,发送信息给子线程的Looper,因此必须有子线程的Looper,为了防止Looper没有初始化,所以通过HandlerThread类,来保证子线程的Looper再被主线程调用时已经初始化。查看全部
-
1.创建主线程的handler,并向子线程发送消息: //主线程的handler Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { Message message = new Message(); threadHandler.sendMessageDelayed(message, 1000);//向子线程发送消息 }; }; 2.创建子线程的handler,向主线程发送消息,要关联一个threadHandler,threadHandler.getLooper()得到一个looper对象 HandlerThread handlerThread = new HandlerThread("handler thread"); handlerThread.start();//不要忘记调用start方法! //子线程的handler threadHandler = new Handler(handlerThread.getLooper()){ @Override public void handleMessage(Message msg) {//处理消息 Message message = new Message(); handler.sendMessageDelayed(message, 1000); } };查看全部
-
子线程与主线程之间的相互通信 1.子线程通过 HandlerThread的thread.getLooper()绑定, 2.在主线程的handler的handlerMessage中调用threadHandler.sendMessageDelay(msg,1000);向子线程发送消息。 3.在子线程中通过handler.sendMessageDelay(msg,1000);向主线程发送消息 4.在一个启动点btn调用主线程的handler.sendEmptyMessage(int x); 5.在一个结束点btn调用handler.removeMessages(x);查看全部
-
1. Handler在创建的时候可以指定Looper,这样通过Handler的sendMessage()方法发送出去的消息就会添加到指定Looper里面的MessageQueue里面去。在不指定Looper的情况下Handler绑定的是创建它的线程的Looper。如果这个线程的Looper不存在,程序将抛出"Can't create handler inside thread that has not called Looper.prepare()"。 2. HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,它自带一个封装好了的Looper成员变量。在其run()方法中,调用Looper.myLooper()获得一个looper对象。 3. HandlerThread的用处 创建Handler时指定的looper,也可以是别的线程创建的。所以Handler中MessageQueue的轮询不一定非要在创建Handler的线程进行,还可以在别的线程中进行。 这个时候我们就需要使用HandlerThread这个类的Looper,这样消息的处理就在新创建的HandlerThread中进行。模拟异步处理,主线程给子线程发送消息,在子线程中处理比较耗时的操作。 mThread = new HandlerThread("Handler Thread");//为新创建的线程指定一个名字,HandlerThread线程独有 mHandler = new Handler(mThread.getLooper()){ public void handleMessage(android.os.Message msg) {... }; };查看全部
举报
0/150
提交
取消