monkey测试Sending Key (ACTION_UP): 82 // KEYCODE_MENU异常分析和处理

最近车厂做monkey测试,出现一个很奇怪的问题,具体报错如下:

//monkey KEYCODE_MENU ACTION_UP
22:18:38.115207  6570  6570 I Monkey  : :Sending Key (ACTION_UP): 82    // KEYCODE_MENU

//崩溃
--------- switch to crash
22:18:38.133137 16255 16255 E AndroidRuntime: FATAL EXCEPTION: main
22:18:38.133137 16255 16255 E AndroidRuntime: Process: net.easyconn, PID: 16255
22:18:38.133137 16255 16255 E AndroidRuntime: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.ViewRootImpl.setView(ViewRootImpl.java:807)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:356)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
22:18:38.133137 16255 16255 E AndroidRuntime:     at d.b.k.k.G(:15)
22:18:38.133137 16255 16255 E AndroidRuntime:     at d.b.k.k.v(:7)
22:18:38.133137 16255 16255 E AndroidRuntime:     at d.b.k.k$e.dispatchKeyEvent(Unknown Source:2)
22:18:38.133137 16255 16255 E AndroidRuntime:     at com.android.internal.policy.DecorView.dispatchKeyEvent(DecorView.java:342)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:5047)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4915)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4436)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4489)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4455)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4595)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4463)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4652)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4436)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4489)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4455)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4463)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4436)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4489)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4455)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4628)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:4789)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2571)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:2081)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:2072)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2548)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.os.MessageQueue.nativePollOnce(Native Method)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.os.MessageQueue.next(MessageQueue.java:326)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.os.Looper.loop(Looper.java:160)
22:18:38.133137 16255 16255 E AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:6718)
22:18:38.133137 16255 16255 E AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
22:18:38.133137 16255 16255 E AndroidRuntime:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
22:18:38.133137 16255 16255 E AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

//中止进程,信号9
22:18:38.229723 16255 16255 I Process : Sending signal. PID: 16255 SIG: 9

系统提示我:Unable to add window -- token null is not valid; is your activity running?

追踪源码发现,报错的位置在ViewRootImpl的setView方法中的

case WindowManagerGlobal.ADD_BAD_APP_TOKEN:

case WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN:

中,可是我的Activity明明好好的在前台放着,应该什么都没干,怎么会setView呢?

由于项目中代码很多,又没有其他错误,于是我决定写一个Helloworld真正什么都不干试一下

1.gradle依赖如下

implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'com.google.android.material:material:1.0.0'

2.MainActivity的代码

public class MainActivity extends AppCompatActivity {

    @Overide
    public void onCreate(Bundle saveInstanceState) {
        super.onCreate(saveInstanceState);
        setContentView(R.layout.main_activity);
    }
}

然后手动模拟发送EVENT_MENU事件

adb shell input keyevent 82

我靠,果然崩了!

这就奇怪了,HelloWorld里面什么代码都没写,难道系统出bug了?

查阅博客应用错误收集 (thinbug.com)得知,在AppCompatActivity中没能处理EVENT_MENU事件导致的异常,要么升级'androidx.appcompat:appcompat:1.0.0'的版本为最新,要么手动让AppCompatActivity监听EVENT_MENU事件,代码如下:

public class MainActivity extends AppCompatActivity {

    @Overide
    public void onCreate(Bundle saveInstanceState) {
        super.onCreate(saveInstanceState);
        setContentView(R.layout.main_activity);

        Window window = appCompatActivity.getWindow();
        Window.Callback callback = window.getCallback();
        MyWindowCallbackWrapper myWindowCallbackWrapper = new MyWindowCallbackWrapper(callback, new WeakReference(this));
        window.setCallback(myWindowCallbackWrapper);
    }

    private static class MyWindowCallbackWrapper extends WindowCallbackWrapper {

        private AppCompatActivity activity;

        public WindowCallbackWrapper(Window.Callback callback, WeakReference weakactivity) {
            super(callback);
            this.activity = weakactivity.get();
        }

        @Override
        public boolean dispatchKeyEvent(KeyEvent event) {
            int keyCode = event.getKeyCode();
            int action = event.getAction();
            if (keyCode == KeyEvent.KEYCODE_MENU && action == KeyEvent.ACTION_DOWN) {
                if (activity.onKeyDown(event.getKeyCode(), event))
                    return true;
            } else if (keyCode == KeyEvent.KEYCODE_MENU && action == KeyEvent.ACTION_UP) {
                if (activity.onKeyUp(event.getKeyCode(), event))
                    return true;
            }
            return super.dispatchKeyEvent(event);
        }
    }
}

你可能感兴趣的:(android,adb,monkey)