Android 线程上的机器人分子runOnUiThread不起作用
runOnUiThread()在线程内执行时似乎不起作用。有人知道解决办法吗 注:我在这里登记了一张罚单-Android 线程上的机器人分子runOnUiThread不起作用,android,unit-testing,testing,robolectric,Android,Unit Testing,Testing,Robolectric,runOnUiThread()在线程内执行时似乎不起作用。有人知道解决办法吗 注:我在这里登记了一张罚单- 测试的结果可能与预期的一样,因为第二个测试阻塞了运行目标Runnable所需的UI线程 第一个测试将通过,因为整个方法是同步执行的。由于您已经在UI线程上,因此在调用activity.runOnUiThread(…)时,将立即执行Runnable。由于锁存为0,因此锁存.await(20,TimeUnit.SECONDS)立即返回,断言为true 在第二个示例中,您启动一个新线程,并在其中
测试的结果可能与预期的一样,因为第二个测试阻塞了运行目标
Runnable
所需的UI线程
第一个测试将通过,因为整个方法是同步执行的。由于您已经在UI线程上,因此在调用activity.runOnUiThread(…)
时,将立即执行Runnable
。由于锁存
为0,因此锁存.await(20,TimeUnit.SECONDS)
立即返回,断言为true
在第二个示例中,您启动一个新线程,并在其中调用activity.runOnUiThread(…)
。由于您不在UI线程上,Runnable
将发布到UI线程上的处理程序
,以便将来异步执行。此时,您继续调用latch.wait(20,TimeUnit.SECONDS)来自UI线程的code>,这意味着Runnable
在此期间无法运行,因为您正在阻止UI线程
20秒后,线程继续运行,但Runnable
从未运行过,因此断言失败,因为didRun()
从未设置为true
下面是一个更新的测试,它允许使用runOnUiThread()
发布的Runnable
运行
@Test
public void inside_a_new_thread() throws Exception {
final Activity activity = Robolectric.setupActivity(Activity.class);
final CountDownLatch latch = new CountDownLatch(1);
final AtomicBoolean didRun = new AtomicBoolean(false);
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
didRun.set(true);
latch.countDown();
}
});
}
});
thread.start();
// sleep current thread to give the new thread a chance to run and post the runnable
Thread.sleep(1000);
// This method will cause the runnable to be executed
Robolectric.flushForegroundThreadScheduler();
// Should immediately return since the runnable has been executed
latch.await(20, TimeUnit.SECONDS);
assertTrue(didRun.get());
}
@Test
public void inside_a_new_thread() throws Exception {
final Activity activity = Robolectric.setupActivity(Activity.class);
final CountDownLatch latch = new CountDownLatch(1);
final AtomicBoolean didRun = new AtomicBoolean(false);
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
didRun.set(true);
latch.countDown();
}
});
}
});
thread.start();
// sleep current thread to give the new thread a chance to run and post the runnable
Thread.sleep(1000);
// This method will cause the runnable to be executed
Robolectric.flushForegroundThreadScheduler();
// Should immediately return since the runnable has been executed
latch.await(20, TimeUnit.SECONDS);
assertTrue(didRun.get());
}