[原] Android performClick无效,UI线程理解
原因
开发过程中遇到button.performClick()无效,原因是View.performClick()需要再UI线程中调用才会有效执行。
响应系统调用的方法(比如报告用户动作的onKeyDown()或一个生命周期回调方法)永远在界面线程中进程,所以onCreate里面调用button的performClick没问题,
而通过code直接调用相当于是代码执行,并不会触发android的UI线程。
什么是UI线程,以下来自官网翻译
当一个应用被启动,系统创建一个执行线程,叫做"main"。这个线程是十分重要的,因为它主管向用户界面控件派发事件。其中包含绘图事件。它也是你的应用与界面工具包(android.widget和 android.view包中的组件)交互的地方。于是main线程也被称为界面线程。
系统不会为每个组件的实例分别创建线程。所有运行于一个进程的组件都在界面线程中被实例化,并且系统对每个组件的调用都在这个线程中派发。因此,响应系统调用的方法(比如报告用户动作的onKeyDown()或一个生命周期回调方法)永远在界面线程中进程。
例如,当用户触摸屏幕上的一个按钮时,你的应用的界面线程把触摸事件派发给控件,然后控件设置它的按下状态再向事件队列发出一个自己界面变得无效的请求,界面线程从队列中取出这个请求并通知这个控件重绘它自己。
http://wiki.eoeandroid.com/Processes_and_Threads
解决方法,最简单的方式
View.post(new Runnable(){ @Override public void run() { button.performClick(); } });
View.post(Runnable)方法。在post(Runnable action)方法里,View获得当前线程(即UI线程)的Handler,然后将action对象post到Handler里。在Handler里,它将传递过来的action对象包装成一个Message(Message的callback为action),然后将其投入UI线程的消息循环中。在Handler再次处理该Message时,有一条分支(未解释的那条)就是为它所设,直接调用runnable的run方法。而此时,已经路由到UI线程里,因此,我们可以毫无顾虑的来更新UI。
Activity.runOnUiThread(new Runnable() { @Override public void run() { button.performClick(); } });
Activity.runOnUiThread(Runnable)把更新ui的代码创建在Runnable中,然后在需要更新ui时,把这个Runnable对象传给Activity.runOnUiThread(Runnable)。 这样Runnable对像就能在ui程序中被调用。如果当前线程是UI线程,那么行动是立即执行。如果当前线程不是UI线程,操作是发布到事件队列的UI线程
android提供了几种常用的方式,用于实现后台线程与UI线程的交互
- 1. handler
- 2. Activity.runOnUIThread(Runnable)
- 3. View.Post(Runnable)
- 4. View.PostDelayed(Runnabe,long)
- 5. AsyncTask