我希望能够让 Espresso
将 Picasso
作为 IdlingResource
进行监控,以便我可以运行 ViewMatcher
成功加载图像后,将出现 s。
通过浏览 Picasso
源代码,我不明白为什么这不起作用。这是我尝试过的:
Picasso picasso = new Picasso.Builder(context).build();
Field dispatcherField = Picasso.class.getDeclaredField("dispatcher");
dispatcherField.setAccessible(true);
try {
Dispatcher dispatcher = (Dispatcher) dispatcherField.get(picasso);
Espresso.registerLooperAsIdlingResource(dispatcher.dispatcherThread.getLooper());
} catch (NoSuchFieldException e) {
throw new PicassoHasBeenRefactoredException();
} catch (Exception e) {
e.printStackTrace();
}
onView(withId(R.id.image_view)).check(matches(withImage(R.drawable.drawable)));
(是的,我知道,反射很烦人,但我找不到另一种方法来获取Looper
的句柄)
但是当尝试从 ImageView
获取 Bitmap
时,会导致此错误:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.graphics.Bitmap android.graphics.drawable.BitmapDrawable.getBitmap()' on a null object reference
为了检查加载图像后测试是否按预期运行,我尝试引入 Thread.sleep(1000)
来代替 IdlingResource
检查并通过了。
是否可以安全地假设 IdlingResource 尚未正确设置,更重要的是,在使用 Espresso 检查 View 之前等待 Picasso 完成加载的正确方法是什么?
最佳答案
我正在使用 IdlingResource 来检查是否还有剩余操作。
请注意,IdlingResource 必须与 Picasso 位于同一包中才能访问受包保护的变量
package com.squareup.picasso;
public class PicassoIdlingResource implements IdlingResource, ActivityLifecycleCallback {
protected ResourceCallback callback;
WeakReference<Picasso> picassoWeakReference;
@Override
public String getName() {
return "PicassoIdlingResource";
}
@Override
public boolean isIdleNow() {
if (isIdle()) {
notifyDone();
return true;
} else {
return false;
}
}
public boolean isIdle() {
return picassoWeakReference == null
|| picassoWeakReference.get() == null
|| picassoWeakReference.get().targetToAction.isEmpty();
}
@Override
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
this.callback = resourceCallback;
}
void notifyDone() {
if (callback != null) {
callback.onTransitionToIdle();
}
}
@Override
public void onActivityLifecycleChanged(Activity activity, Stage stage) {
switch (stage) {
case CREATED:
picassoWeakReference = new WeakReference<>(Picasso.with(activity));
break;
case STOPPED:
// Clean up reference
picassoWeakReference = null;
break;
default: // NOP
}
}
}
我认为不需要使用 WeakReference,但它也没有坏处。
此外,我还发现了一种情况,它不会等到 Picasso 完成(使用 .load(null) 时)。因此,请自行承担使用风险,如果您改进了它,请回来。
有关完整详细信息和用法,请参阅要点 ( https://gist.github.com/Maragues/0c0db81a137c8d067396 )
关于android - 在 Espresso 中监控 Picasso 的 IdlingResource,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32779549/