我有一个利用admob的应用程序,我使用robolectric进行活动单元测试。最近,当我尝试在某个单元测试课程中添加第二个活动启动时,我遇到了僵局。
我将尽力解决这个问题。我创建了一个最小的工作示例。
我面临的僵局是:
"Measurement Worker":
at org.robolectric.util.Scheduler.remove(Scheduler.java:191)
- waiting to lock <0x00000006c2ccf310> (a org.robolectric.util.Scheduler)
at org.robolectric.shadows.ShadowMessage.unschedule(ShadowMessage.java:35)
at org.robolectric.shadows.ShadowMessage.recycleUnchecked(ShadowMessage.java:50)
at java.lang.invoke.LambdaForm$DMH/1366974691.invokeVirtual_L_V(LambdaForm$DMH)
at java.lang.invoke.LambdaForm$BMH/534224098.reinvoke(LambdaForm$BMH)
at java.lang.invoke.LambdaForm$MH/385364354.guardWithCatch(LambdaForm$MH)
at java.lang.invoke.LambdaForm$MH/370640320.delegate(LambdaForm$MH)
at java.lang.invoke.LambdaForm$MH/1706920634.guard(LambdaForm$MH)
at java.lang.invoke.LambdaForm$MH/1997654846.linkToCallSite(LambdaForm$MH)
at android.os.Message.recycleUnchecked(Message.java)
at android.os.MessageQueue.$$robo$$android_os_MessageQueue$removeMessages(MessageQueue.java:698)
- locked <0x00000006c2ccf2c8> (a android.os.MessageQueue)
at java.lang.invoke.LambdaForm$DMH/194706439.invokeSpecial_L4_V(LambdaForm$DMH)
at java.lang.invoke.LambdaForm$MH/1114217759.guardWithCatch(LambdaForm$MH)
at java.lang.invoke.LambdaForm$reinvoker/856894939.dontInline(LambdaForm$reinvoker)
at java.lang.invoke.LambdaForm$MH/585248983.guard(LambdaForm$MH)
at java.lang.invoke.LambdaForm$MH/123955857.linkToCallSite(LambdaForm$MH)
at android.os.MessageQueue.removeMessages(MessageQueue.java)
at android.os.Handler.$$robo$$android_os_Handler$removeCallbacks(Handler.java:513)
at java.lang.invoke.LambdaForm$DMH/984196143.invokeSpecial_LL_V(LambdaForm$DMH)
at java.lang.invoke.LambdaForm$MH/1603578033.guardWithCatch(LambdaForm$MH)
at java.lang.invoke.LambdaForm$reinvoker/324572218.dontInline(LambdaForm$reinvoker)
at java.lang.invoke.LambdaForm$MH/910145967.guard(LambdaForm$MH)
at java.lang.invoke.LambdaForm$MH/917035733.linkToCallSite(LambdaForm$MH)
at android.os.Handler.removeCallbacks(Handler.java)
at com.google.android.gms.measurement.internal.zzab.cancel(Unknown Source)
at com.google.android.gms.measurement.internal.zzab.zzv(Unknown Source)
at com.google.android.gms.measurement.internal.zzeg.zzd(Unknown Source)
at com.google.android.gms.measurement.internal.zzeg.zza(Unknown Source)
at com.google.android.gms.measurement.internal.zzee.run(Unknown Source)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at com.google.android.gms.measurement.internal.zzbx.run(Unknown Source)
"SDK 26 Main Thread":
at org.robolectric.shadows.ShadowMessageQueue$1.run(ShadowMessageQueue.java:106)
- waiting to lock <0x00000006c2ccf2c8> (a android.os.MessageQueue)
at org.robolectric.util.Scheduler$ScheduledRunnable.run(Scheduler.java:386)
at org.robolectric.util.Scheduler.runOneTask(Scheduler.java:278)
- locked <0x00000006c2ccf310> (a org.robolectric.util.Scheduler)
at org.robolectric.util.Scheduler.advanceTo(Scheduler.java:260)
- locked <0x00000006c2ccf310> (a org.robolectric.util.Scheduler)
at org.robolectric.util.Scheduler.advanceBy(Scheduler.java:243)
- locked <0x00000006c2ccf310> (a org.robolectric.util.Scheduler)
at org.robolectric.util.Scheduler.advanceBy(Scheduler.java:233)
- locked <0x00000006c2ccf310> (a org.robolectric.util.Scheduler)
at org.robolectric.util.Scheduler.setIdleState(Scheduler.java:88)
- locked <0x00000006c2ccf310> (a org.robolectric.util.Scheduler)
at org.robolectric.util.Scheduler.unPause(Scheduler.java:123)
- locked <0x00000006c2ccf310> (a org.robolectric.util.Scheduler)
at org.robolectric.shadows.ShadowLooper.unPause(ShadowLooper.java:347)
at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:398)
at org.robolectric.android.controller.ActivityController.visible(ActivityController.java:161)
at org.robolectric.android.internal.LocalActivityInvoker.startActivity(LocalActivityInvoker.java:44)
at androidx.test.core.app.ActivityScenario.launch(ActivityScenario.java:207)
at androidx.test.core.app.ActivityScenario.launch(ActivityScenario.java:184)
at name.example.DeadlockTest.launchActivity(DeadlockTest.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$0(SandboxTestRunner.java:256)
at org.robolectric.internal.SandboxTestRunner$2$$Lambda$29/942518407.run(Unknown Source)
at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:89)
at org.robolectric.internal.bytecode.Sandbox$$Lambda$30/1943325854.call(Unknown Source)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Found 1 deadlock.
单元测试代码:
@RunWith(RobolectricTestRunner.class)
public class DeadlockTest {
@Test
public void launchActivity() {
for (int i=0; i<2; i++){
try (ActivityScenario<DeadlockActivity> scenario = ActivityScenario.launch(DeadlockActivity.class)) {
}
}
}
}
活动代码:
public class DeadlockActivity extends Activity {
private AdView adView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
adView = new AdView(this);
adView.setAdSize(AdSize.BANNER);
adView.setAdUnitId("ca-app-pub-3940256099942544/6300978111");
AdRequest adRequest = new AdRequest.Builder().build();
adView.loadAd(adRequest);
}
@Override
public void onDestroy() {
adView.destroy();
super.onDestroy();
}
}
app / build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example"
minSdkVersion 21
versionCode 1
}
testOptions.unitTests.includeAndroidResources true
}
dependencies {
implementation 'com.google.android.gms:play-services-ads:17.2.0'
implementation 'com.google.firebase:firebase-core:16.0.8'
testImplementation 'androidx.test.ext:junit:1.1.0'
testImplementation 'org.robolectric:robolectric:4.2'
}
在我的环境中,死锁永远不会在循环的第一次迭代中发生,并且始终在第二次迭代中发生。
有什么想法吗?
答案 0 :(得分:0)
将Firebase依赖关系更新为仅发行版解决了单元测试死锁问题。
dependencies {
implementation 'com.google.android.gms:play-services-ads:17.2.0'
releaseImplementation 'com.google.firebase:firebase-core:16.0.8'
testImplementation 'androidx.test.ext:junit:1.1.0'
testImplementation 'org.robolectric:robolectric:4.2'
}