在代码中模拟人的点击按钮操作

2019-04-13 14:30发布

button.performClick();button是自己写的按钮的名字。performClick()方法是执行点击事件。button.performClick();执行之后无效的原因:
开发过程中遇到button.performClick()无效,原因是View.performClick()需要再UI线程中调用才会有效执行。响应系统调用的方法(比如报告用户动作的onKeyDown()或一个生命周期回调方法)永远在界面线程中进程,所以onCreate里面调用button的performClick没问题, 
而通过code直接调用相当于是代码执行,并不会触发android的UI线程。

什么是UI线程,以下来自官网翻译

当一个应用被启动,系统创建一个执行线程,叫做"main"。这个线程是十分重要的,因为它主管向用户界面控件派发事件。其中包含绘图事件。它也是你的应用与界面工具包(android.widget和 android.view包中的组件)交互的地方。于是main线程也被称为界面线程。系统不会为每个组件的实例分别创建线程。所有运行于一个进程的组件都在界面线程中被实例化,并且系统对每个组件的调用都在这个线程中派发。因此,响应系统调用的方法(比如报告用户动作的onKeyDown()或一个生命周期回调方法)永远在界面线程中进程。例如,当用户触摸屏幕上的一个按钮时,你的应用的界面线程把触摸事件派发给控件,然后控件设置它的按下状态再向事件队列发出一个自己界面变得无效的请求,界面线程从队列中取出这个请求并通知这个控件重绘它自己。

解决方法,最简单的方式

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如果在activity中使用this代替。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 
注意事项   如果同时使用了view.setOnTouchListener()方法,则有可能存在拦截view.performClick()的响应事件, 因为当view.OnTouchEvent()在event.getAction() == MotionEvent.ACTION_DOWN时返回false, 系统会认为view不需要处理Touch事件,则后续的Touch事件(move、up、click)就不会被传进来 。 所以也不会触发view.performClick(),而view.setOnTouchListener()相当于是重写了view.OnTouchEvent(), 所以在写view的TouchListener处理时,需要留意view是否存在点击事件监听,如果有,则在适当的位置使用view.performClick()触发点击事件android中的UI操作都必须在主线程中处理的,在涉及UI操作时通常可以: 1.使用mHandler = new Handler(Looper.getMainLooper()),然后在handler中处理操作; 2.使用 Activity.runOnUiThread()方法。而button.performClick();是需要在是ui操作,所有需要在ui线程中去执行的。