gpt4 book ai didi

android - 线程上的 robolectric runOnUiThread 不起作用

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:15:10 27 4
gpt4 key购买 nike

runOnUiThread() 在线程内执行时似乎不起作用。有人知道解决方法吗?

注意:我在这里提交了工单 - https://github.com/robolectric/robolectric/issues/2479

import android.app.Activity;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.annotation.Config;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import static org.junit.Assert.assertTrue;

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
public class RunOnUiThreadTest {

/**
* Works
* @throws Exception
*/
@Test
public void inside_the_main_thread() throws Exception {
final Activity activity = Robolectric.setupActivity(Activity.class);
final CountDownLatch latch = new CountDownLatch(1);
final AtomicBoolean didRun = new AtomicBoolean(false);

activity.runOnUiThread(new Runnable() {
@Override
public void run() {
didRun.set(true);
latch.countDown();
}
});

latch.await(20, TimeUnit.SECONDS);
assertTrue(didRun.get());
}

/**
* Fails
* @throws Exception
*/
@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();

latch.await(20, TimeUnit.SECONDS);
assertTrue(didRun.get());
}

}

最佳答案

由于第二个测试阻止了运行目标 Runnable 所需的 UI 线程,因此测试的结果很可能符合预期。

第一个测试会通过,因为整个方法是同步执行的。由于您已经在 UI 线程上,因此当调用 activity.runOnUiThread(...) 时,Runnable 将立即执行。由于 latch 为 0 latch.await(20, TimeUnit.SECONDS) 立即返回并且断言为真。

在第二个示例中,您启动了一个新线程并从其中调用 activity.runOnUiThread(...)。由于您不在 UI 线程上,因此 Runnable 被发布到 UI 线程上的 Handler 以在将来异步执行。此时,您继续从 UI 线程调用 latch.await(20, TimeUnit.SECONDS);,这意味着 Runnable 无法在此期间运行,因为您阻止了界面线程。

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());
}

关于android - 线程上的 robolectric runOnUiThread 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37549313/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com