I'm using Robolectric 3 rc2 with OkHttp Mock WebServer and Google Play Services.
I need to test the parsing of a json and related processing associated to it using the mock server and the server client have already using. The whole server client call is running in background with okhttp asynchronous call. The whole project if a library project.
Full code here
Gradle config :
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'
I'm running the test why command line :
./gradlew mymodule:clean mymodule:assembleDebug mymodule:testDebug --info
I've got an error related to google play services java.lang.IllegalStateException: Calling this from your main thread can lead to deadlock
I'm surely doing something wrong when gettign AdvertisingId...
Complete stacktrace :
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)
java.lang.RuntimeException: java.lang.IllegalStateException: Calling this from your main thread can lead to deadlock
The message from the exception explicitly describes what you are doing wrong. Apparently you should not call AdvertisingIdClient on UI thread because the library doesn't allow it (the reason is stated above. It could lead to deadlock).
Therefore, you have to use AsyncTask or any other background task libraries in order to call this 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();
This is how you call getAdvertisingIdInfo method in AdvertisingIdClient class using AsyncTask . Comment if you have any other question :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.