2016-07-15 90 views
1

我已经使用了一种服务,以3秒为间隔将代码发布到处理程序,以继续生成简单的触摸事件(按下按钮)。在后台线程中模拟Android中的触摸事件

这是该服务的代码:

public class BackgroundTouchService extends IntentService 
{ 
    public BackgroundTouchService() { 
     super("BackgroundTouchService"); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) 
    { 
     final MotionEvent event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), 
       MotionEvent.ACTION_BUTTON_PRESS, 400, 400, 0); 

     final Handler handler = new Handler(); 
     handler.post(new Runnable() { 
      @Override 
      public void run() 
      { 
       View v = new View(getApplication()); 
       v.onTouchEvent(event); 
       handler.postDelayed(this, 3000); 
      } 
     }); 
    } 
} 

以我UI,我已经覆盖有按钮在屏幕上(用适当的监听器),这样我可以很容易地发现已经按下了哪个按钮。然而,主要活动加载,然后没有任何反应。为什么是这样?

编辑: 由于VojtěchSáze正确指出,上述代码中的处理程序与主线程没有关联,因此无法通过生成触摸事件来修改UI。因此,我在主要活动本身编写了处理程序的代码:

public class MainActivity extends AppCompatActivity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    startTouch(); 
} 

private void startTouch() 
{ 
    final MotionEvent event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), 
       MotionEvent.ACTION_BUTTON_PRESS,400.0f, 400.0f, 0); 

     final Handler handler = new Handler(); 
     handler.post(new Runnable() { 
      @Override 
      public void run() 
      { 
       onTouchEvent(event); 
       handler.postDelayed(this, 3000); 
      } 
     }); 
    } 
} 

但是,这仍然没有任何作用。有任何想法吗?

SOLUTION: 好,所以我原本指定ACTION_BUTTON_PRESS的MotionEvent.obtain方法的事件类型的参数,但是,当我用不同的活动来分别指定ACTION_DOWN和ACTION_UP,这似乎工作。 任何解释为什么发生这种情况是受欢迎的。 万一有人需要这个,这里是代码:

final MotionEvent event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), 
       MotionEvent.ACTION_DOWN,400.0f, 400.0f, 0); 
     final MotionEvent event2 = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), 
       MotionEvent.ACTION_UP, 400.0f, 400.0f, 0); 

    final Handler handler = new Handler(); 
    handler.post(new Runnable() { 
     @Override 
     public void run() 
     { 
      dispatchTouchEvent(event); 
      dispatchTouchEvent(event2); 
      handler.postDelayed(this, 3000); 
     } 
    }); 

回答

0

我不知道这是否会有所帮助。但肯定是有与

final Handler handler = new Handler(); 

documentation问题:

默认的构造同伙这个处理器与乐句当前线程。如果此线程没有活套,则此处理程序将无法接收消息,因此引发异常。

但是,您在onHandleIntent()中没有主线程。您需要在主线程中创建Handler

+0

你说得对。如果处理程序必须生成触摸事件(它被分类为修改UI,因此只能在主线程中完成),则该处理程序必须与主线程关联。请检查编辑。 –

2

我认为您需要使用dispatchTouchEvent方法将触摸事件发送到视图。

+0

此方法将触发事件发送给哪个视图?我们称之为没有对象。 –

+0

我试过了,它仍然不起作用 –

+0

当您在没有对象的情况下调用它时,方法调用将在“this”上。所以我认为在你的情况下,这将是活动实例。我以为我知道事件传播是如何在Android中发生的,但我有一些概念错误。我偶然看到这段视频,非常清楚地解释事件是如何从父母到孩子的。请通过https://newcircle.com/s/post/1567/mastering_the_android_touch_system – prashant

0

只需使用下面的代码。使用Android Handler,您还需要使用Looper发布操作。

final Handler handler = new Handler(Looper.getMainLooper()); 
    handler.post(new Runnable() { 
     @Override 
     public void run() 
     { 
      onTouchEvent(event); 
      handler.postDelayed(this, 3000); 
     } 
    });