Issue
in the @Before function of one of my tests i am trying to register espresso idlingResource but i keep getting error that it needs to be run off the main thread. here is what i have so far:
@Before
public void setUp() throws Exception {
mIntentsTestRule.getActivity().sharedPrefRepo.clearAll();
new Thread(){
@Override
public void run() {
super.run();
IdlingResource loadingDialogIdlingResource = new LoadingDialogIdlingResource();
IdlingRegistry.getInstance().register(loadingDialogIdlingResource);
}
}.start();
}
but this kind of makes no sense. im registering these things on another thread and yet i'll continue running my tests before it completes ? what is the way to really register these things ? i have created a unregister function as well in teardown which looks like this:
@After
public void tearDown() throws Exception {
//handle any clean up
mIntentsTestRule.getActivity().sharedPrefRepo.clearAll();
freeIdlingResources();
mIntentsTestRule.getActivity().finish();
}
the error is below if i do not use a thread:
java.lang.RuntimeException: java.util.concurrent.ExecutionException: java.lang.RuntimeException: This method can not be called from the main application thread
at android.support.test.espresso.base.IdlingResourceRegistry.runSynchronouslyOnMainThread(IdlingResourceRegistry.java:314)
at android.support.test.espresso.base.IdlingResourceRegistry.sync(IdlingResourceRegistry.java:90)
at android.support.test.espresso.Espresso.onView(Espresso.java:69)
please note: The former Espresso.registerIdlingResources() method has been deprecated in by IdlingRegistry via getInstance().register().
update: here is my idlresource code:
public class LoadingDialogIdlingResource implements IdlingResource {
private ResourceCallback resourceCallback;
private boolean isIdle;
@Override
public String getName() {
return LoadingDialogIdlingResource.class.getName();
}
@Override
public boolean isIdleNow() {
if (isIdle) return true;
Activity activity = getCurrentActivity();
if (activity == null) return false;
Fragment f = activity.getFragmentManager().findFragmentByTag(ProgressDialogFragment.class.getName());
isIdle = f == null;
if (isIdle) {
resourceCallback.onTransitionToIdle();
}
return isIdle;
}
public Activity getCurrentActivity() {
final Activity[] currentActivity = {null};
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable(){
public void run(){
Collection<Activity> resumedActivity = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED);
Iterator<Activity> it = resumedActivity.iterator();
currentActivity[0] = it.next();
}
});
return currentActivity[0];
}
@Override
public void registerIdleTransitionCallback(
ResourceCallback resourceCallback) {
this.resourceCallback = resourceCallback;
}
}
Solution
The problem was in this block of code:
public Activity getCurrentActivity() {
final Activity[] currentActivity = {null};
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable(){
public void run(){
Collection<Activity> resumedActivity = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED);
Iterator<Activity> it = resumedActivity.iterator();
currentActivity[0] = it.next();
}
});
return currentActivity[0];
}
Calling runOnMainSync
is forbidden here. I resolved the issue by simply passing in the fragment manager into the constructor.
Answered By - j2emanue
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.