我正在使用 Robolectric 3 rc2 与OkHttp Mock WebServer和Google Play服务。
我需要测试json的解析以及使用模拟服务器和服务器客户端已经使用的相关处理。整个服务器客户端调用在后台中运行,并带有 okhttp异步调用。整个项目如果是图书馆项目。
完整代码 here
Gradle配置:
testCompile 'org.apache.maven:maven-ant-tasks:2.1.3'
testCompile ("org.robolectric:robolectric:3.0-rc2"){
exclude module: 'commons-logging'
exclude module: 'httpclient'
}
testCompile 'com.google.android.gms:play-services:7.0.0'
testCompile ("org.robolectric:shadows-play-services:3.0-rc2"){
exclude module: 'commons-logging'
exclude module: 'httpclient'
}
testCompile 'org.robolectric:shadows-support-v4:3.0-rc2'
testCompile 'org.assertj:assertj-core:1.7.0'
testCompile 'com.squareup.okhttp:mockwebserver:1.2.1'
我正在运行测试为什么命令行:
./ gradlew mymodule:clean mymodule:assembleDebug mymodule:testDebug --info
我收到与Google Play服务相关的错误 java.lang.IllegalStateException: Calling this from your main thread can lead to deadlock
当gettign AdvertisingId ......我肯定做错了什么......
完成堆栈跟踪:
java.lang.RuntimeException: java.lang.IllegalStateException: Calling this from your main thread can lead to deadlock
at org.robolectric.util.SimpleFuture.run(SimpleFuture.java:57)
at org.robolectric.shadows.ShadowAsyncTask$2.run(ShadowAsyncTask.java:93)
at org.robolectric.util.Scheduler.runOrQueueRunnable(Scheduler.java:218)
at org.robolectric.util.Scheduler.postDelayed(Scheduler.java:73)
at org.robolectric.util.Scheduler.post(Scheduler.java:60)
at org.robolectric.shadows.ShadowAsyncTask.execute(ShadowAsyncTask.java:90)
at android.os.AsyncTask.execute(AsyncTask.java)
at com.example.sdk.adServer.ServerClient.<init>(ServerClient.java:101)
at com.example.sdk.ServerClientTest.testLongTask(ServerClientTest.java:123)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:235)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:168)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:86)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:64)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:50)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:106)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:360)
at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: Calling this from your main thread can lead to deadlock
at com.google.android.gms.common.internal.zzx.zzbe(Unknown Source)
at com.google.android.gms.common.internal.zzx.zzbe(Unknown Source)
at com.google.android.gms.ads.identifier.AdvertisingIdClient.finish(Unknown Source)
at com.google.android.gms.ads.identifier.AdvertisingIdClient.finish(Unknown Source)
at com.google.android.gms.ads.identifier.AdvertisingIdClient.getAdvertisingIdInfo(Unknown Source)
at com.google.android.gms.ads.identifier.AdvertisingIdClient.getAdvertisingIdInfo(Unknown Source)
at com.example.sdk.adServer.ServerClient$RetrieveAdvertisingId.doInBackground(ServerClient.java:459)
at com.example.sdk.adServer.ServerClient$RetrieveAdvertisingId.doInBackground(ServerClient.java:452)
at org.robolectric.util.ReflectionHelpers$3.run(ReflectionHelpers.java:144)
at org.robolectric.util.ReflectionHelpers.traverseClassHierarchy(ReflectionHelpers.java:241)
at org.robolectric.util.ReflectionHelpers.callInstanceMethod(ReflectionHelpers.java:138)
at org.robolectric.shadows.ShadowAsyncTaskBridge.doInBackground(ShadowAsyncTaskBridge.java:20)
at org.robolectric.shadows.ShadowAsyncTask$BackgroundWorker.call(ShadowAsyncTask.java:147)
at org.robolectric.util.SimpleFuture.run(SimpleFuture.java:52)
答案 0 :(得分:-1)
java.lang.RuntimeException: java.lang.IllegalStateException: Calling this from your main thread can lead to deadlock
来自异常的消息明确描述了您所做的错误。显然你不应该在UI线程上调用AdvertisingIdClient,因为库不允许它(原因如上所述。它可能导致死锁)。
因此,您必须使用 AsyncTask 或任何其他后台任务库才能调用此API。
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
AdvertisingIdClient.Info idInfo;
String advertId = null;
try {
idInfo = AdvertisingIdClient.getAdvertisingIdInfo(context);
advertId = idInfo.getId();
} catch (GooglePlayServicesNotAvailableException|GooglePlayServicesRepairableException|IOException e) {
e.printStackTrace();
}
return advertId;
}
@Override
protected void onPostExecute(final String advertId) {
KakaoTaskQueue.getInstance().addTask(new KakaoResultTask<EventsLogResponse>(callback) {
@Override
public EventsLogResponse call() throws Exception {
if (advertId == null)
throw new IllegalAccessException("Could not get adid from the device.");
rootEvent.setFrom(advertId);
return EventsApi.requestLoggingEvents(rootEvent, leafEvents);
}
});
}
};
task.execute();
这是您使用 AsyncTask 在 AdvertisingIdClient 类中调用 getAdvertisingIdInfo 方法的方法。如果您有任何其他问题,请评论:)