3

Android アプリにいくつかの実装テストがあり、Activity のメソッド onOptionsItemSelected() をテストしたいと考えています。

そのために、Instrumentation のinvokeMenuActionSyncメソッドを使用します。

これは Android の新しいバージョンでは問題なく動作しますが、古いバージョン (API10 など) では onOptionsItemSelected() メソッドが呼び出されるようには見えません。

私は他の方法と組み合わせてみました:

if (getInstrumentation().invokeMenuActionSync(activity, R.id.menu_refresh, 0 /* flags */) ||
    getInstrumentation().invokeContextMenuAction(activity, R.id.menu_refresh, 0 /* flags */)) {
   // verify 
}

変化なし。

AppCompat ActionBar を使用しています。

これを常に呼び出すより良い方法はありますか、または古い API レベルで使用して 2 つを切り替える方法はありますか?

4

1 に答える 1

0

インストルメンテーション クラスでサポート メニューを呼び出すことがわかった唯一の方法は、醜いリフレクション コードを使用することです (「init」部分の一部のフィールドとクラスは必要ない場合があります。申し訳ありませんが、他のコードにも使用します)。

// support part
private static Class<?> actionBarActivitySupportClass;  
private static Field mImplField;
private static Class<?> actionBarActivityDelegateBaseClass;
private static Field mActionModeSupportField;
private static Class<?> actionModeSupportImplClass;
private static Field mMenuActionModeSupportField;
private static Class<?> menuBuilderSupportClass;
private static Field mVisibleItemsSupportField;
private static Field mCallbackActionModeSupportField;
private static Class<?> callbackWrapperSupportClass;
private static Field mWrappedSupportField;
private static Method onMenuItemSelectedSupportmethod;
private static Field mActionBarSupportView; 
private static Class<?> actionBarViewSupportClass;
private static Field mOptionMenuSupportField;
private static Method dispatchMenuItemSelected;

static {
    init();
}

private static void init() {
    try {
        actionBarActivitySupportClass = Class.forName("android.support.v7.app.ActionBarActivity"); //$NON-NLS-1$
        mImplField = actionBarActivitySupportClass.getDeclaredField("mImpl"); //$NON-NLS-1$
        mImplField.setAccessible(true);
        actionBarActivityDelegateBaseClass = Class.forName("android.support.v7.app.ActionBarActivityDelegateBase"); //$NON-NLS-1$
        mActionModeSupportField = actionBarActivityDelegateBaseClass.getDeclaredField("mActionMode"); //$NON-NLS-1$
        mActionModeSupportField.setAccessible(true);
        actionModeSupportImplClass = Class.forName("android.support.v7.app.ActionBarImplBase$ActionModeImpl"); //$NON-NLS-1$
        mMenuActionModeSupportField = actionModeSupportImplClass.getDeclaredField("mMenu"); //$NON-NLS-1$
        mMenuActionModeSupportField.setAccessible(true);
        menuBuilderSupportClass = Class.forName("android.support.v7.internal.view.menu.MenuBuilder"); //$NON-NLS-1$
        mVisibleItemsSupportField = menuBuilderSupportClass.getDeclaredField("mVisibleItems"); //$NON-NLS-1$
        mVisibleItemsSupportField.setAccessible(true);
        mCallbackActionModeSupportField = actionModeSupportImplClass.getDeclaredField("mCallback");  //$NON-NLS-1$
        mCallbackActionModeSupportField.setAccessible(true);
        callbackWrapperSupportClass = Class.forName("android.support.v7.app.ActionBarActivityDelegateBase$ActionModeCallbackWrapper"); //$NON-NLS-1$
        mWrappedSupportField = callbackWrapperSupportClass.getDeclaredField("mWrapped"); //$NON-NLS-1$
        mWrappedSupportField.setAccessible(true);
        onMenuItemSelectedSupportmethod = actionModeSupportImplClass.getDeclaredMethod("onMenuItemSelected", new Class[]{menuBuilderSupportClass,MenuItem.class}); //$NON-NLS-1$
        onMenuItemSelectedSupportmethod.setAccessible(true);
        mActionBarSupportView = actionBarActivityDelegateBaseClass.getDeclaredField("mActionBarView"); //$NON-NLS-1$
        mActionBarSupportView.setAccessible(true);
        actionBarViewSupportClass = Class.forName("android.support.v7.internal.widget.ActionBarView");  //$NON-NLS-1$
        mOptionMenuSupportField = actionBarViewSupportClass.getDeclaredField("mOptionsMenu"); //$NON-NLS-1$
        mOptionMenuSupportField.setAccessible(true);
        dispatchMenuItemSelected = menuBuilderSupportClass.getDeclaredMethod("dispatchMenuItemSelected", new Class[]{menuBuilderSupportClass,MenuItem.class}); //$NON-NLS-1$
        dispatchMenuItemSelected.setAccessible(true);
    } catch (ClassNotFoundException e) {
        System.out.println("support class not loaded "+e.getMessage()); //$NON-NLS-1$
    } catch (SecurityException e) {
        System.out.println("support class not loaded "+e.getMessage()); //$NON-NLS-1$
    } catch (NoSuchFieldException e) {
        System.out.println("support class not loaded "+e.getMessage()); //$NON-NLS-1$
    } catch (NoSuchMethodException e) {
        System.out.println("support class not loaded "+e.getMessage()); //$NON-NLS-1$
    }

}

public static void invokeMenu(Instrumentation instrumentation,final Activity activity,final Object item) {
    if ((mImplField != null) && (actionBarActivitySupportClass != null) && (actionBarActivitySupportClass.isInstance(activity)) 
            && (mActionBarSupportView != null) && (mOptionMenuSupportField != null) && (dispatchMenuItemSelected != null)) { 
        activity.runInUiThread(new Runnable() {
            @Override
            public void run() {
                try {
                    Object actionBarActivityDelegateBase = mImplField.get(activity);                
                    if (actionBarActivityDelegateBase != null) {
                        Object actionBarView = mActionBarSupportView.get(actionBarActivityDelegateBase);
                        if (actionBarView != null) {
                            Object mOptionMenu = mOptionMenuSupportField.get(actionBarView);                        
                            dispatchMenuItemSelected.invoke(mOptionMenu, new Object[]{mOptionMenu,item});                       
                        }
                    }                       
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        });
    } else {
        // good old classic way
        instrumentation.invokeMenuActionSync(activity, ((MenuItem)item).getItemId(), 0);
    }

}
于 2015-02-02T13:27:46.873 に答える