InputMethodService的Instrumentation测试用例

Zda*_*daR 5 android android-input-method servicetestcase android-service-binding android-instrumentation

我已经扩展了InputMethodService类来创建我的自定义IME.但是,我正在努力编写有效的Instrumentation测试用例来验证行为.以前Service,可以使用测试ServiceTestCase<YourServiceClass>.但它似乎已被弃用,新格式看起来像这样.现在在给定的指导方针中,我正在努力解决这个片段:

CustomKeyboardService service =
            ((CustomKeyboardService.LocalBinder) binder).getService();
Run Code Online (Sandbox Code Playgroud)

由于我正在扩展InputMethodService,它已经抽象了IBinder,我怎样才能LocalBinder获得这个代码片段的运行?目前,此代码段抛出以下异常:

java.lang.ClassCastException:android.inputmethodservice.IInputMethodWrapper无法强制转换为com.osrc.zdar.customkeyboard.CustomKeyboardService $ LocalBinder

扩展类看起来像:

public class CustomKeyboardService extends InputMethodService {

    // Some keyboard related stuff

    public class LocalBinder extends Binder {

        public CustomKeyboardService getService() {
            // Return this instance of LocalService so clients can call public methods.
            return CustomKeyboardService.this;
        }
    }

    // Some keyboard related stuff

}
Run Code Online (Sandbox Code Playgroud)

如何扩展我的自定义类,以便CustomKeyboardService service = ((CustomKeyboardService.LocalBinder) binder).getService();不返回错误?

这是我的测试用例代码:

@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest2 {
    @Rule
    public final ServiceTestRule mServiceRule = new ServiceTestRule();

    @Test
    public void testWithBoundService() throws TimeoutException {
        // Create the service Intent.
        Intent serviceIntent =
                new Intent(InstrumentationRegistry.getTargetContext(), CustomKeyboardService.class);

        // Bind the service and grab a reference to the binder.
        IBinder binder = mServiceRule.bindService(serviceIntent);

        // Get the reference to the service, or you can call public methods on the binder directly.
        //  This Line throws the error
        CustomKeyboardService service =
                ((CustomKeyboardService.LocalBinder) binder).getService();
    }

}
Run Code Online (Sandbox Code Playgroud)

您还可以在Github上查看OimeKeyboard以获取完整的源代码,并提交带有效仪器测试用例的PR.

Hit*_*ker 0

我也遇到了同样的问题,请查看以下链接的解决方案。
更新了链接中的代码片段:

@Rule
public final ServiceTestRule mServiceRule = new ServiceTestRule();

private MyKeyboard retrieveMyKeyboardInstance(IBinder binder) {
    try {
        Class wrapperClass = Class.forName("android.inputmethodservice.IInputMethodWrapper");
        Field mTargetField = wrapperClass.getDeclaredField("mTarget");
        mTargetField.setAccessible(true);

        WeakReference<MyKeyboard> weakReference = (WeakReference<MyKeyboard>) mTargetField.get(binder);
        return weakReference.get();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

public void validateEditTextWithKeyboardInput() throws TimeoutException {
    ...
    Intent serviceIntent = new Intent(InstrumentationRegistry.getTargetContext(), MyKeyboard.class);
    IBinder binder = mServiceRule.bindService(serviceIntent);
    MyKeyboard keyboard = retrieveMyKeyboardInstance(binder);

    ...
}
Run Code Online (Sandbox Code Playgroud)

来自: https: //github.com/sealor/prototype-Android-Espresso-Keyboard-Testing