我正在使用Flutter开发RealWear HMT-1的应用程序。这是一台Android工业坚固型计算机,它戴在头上并由语音控制。 我正在使用Flutter语义机制来拦截语音命令并模拟小部件上的手势,例如单击按钮。 我花了大约3个月的时间进行开发,并且在应用程序方面没有遇到任何问题,一切都像在我自己的设备上一样具有吸引力,但是几天前,我们向其他公司提供了我们的应用程序,但是它在第一个语音命令上崩溃了,导致该设备甚至在我们的应用程序外部也无法对语音命令做出反应。这至少发生在他们的2个设备上。 我的及其设备均具有相同的固件版本。 我检查了logcat日志,发现他们的语音识别服务在收到AccessibilityEvent并尝试对其调用getPackageName()然后对其结果调用toString()时崩溃。似乎getPackageName返回null,因为toString()调用上有NPE,这是堆栈跟踪:
07-10 11:46:32.810 3219 3219 E AndroidRuntime: FATAL EXCEPTION: main
07-10 11:46:32.810 3219 3219 E AndroidRuntime: Process: com.realwear.wearhf, PID: 3219
07-10 11:46:32.810 3219 3219 E AndroidRuntime: java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String java.lang.CharSequence.toString()' on a null object reference
07-10 11:46:32.810 3219 3219 E AndroidRuntime: at com.realwear.wearhf.MainService.onAccessibilityEvent(Unknown Source:25)
07-10 11:46:32.810 3219 3219 E AndroidRuntime: at android.accessibilityservice.AccessibilityService$2.onAccessibilityEvent(AccessibilityService.java:1524)
07-10 11:46:32.810 3219 3219 E AndroidRuntime: at android.accessibilityservice.AccessibilityService$IAccessibilityServiceClientWrapper.executeMessage(AccessibilityService.java:1710)
07-10 11:46:32.810 3219 3219 E AndroidRuntime: at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:37)
07-10 11:46:32.810 3219 3219 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106)
07-10 11:46:32.810 3219 3219 E AndroidRuntime: at android.os.Looper.loop(Looper.java:164)
07-10 11:46:32.810 3219 3219 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6518)
07-10 11:46:32.810 3219 3219 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
07-10 11:46:32.810 3219 3219 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:443)
07-10 11:46:32.810 3219 3219 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
这是他们的服务的反编译片段,它在哪里崩溃:
String str = this.f603z;
if (str == null || !str.equals(accessibilityEvent.getPackageName().toString())) {
this.f603z = null;
if (accessibilityEvent.getPackageName() == null || !accessibilityEvent.getPackageName().equals(getPackageName())) {
...
这就是Flutter创建AccessibilityEvent的方式:
private AccessibilityEvent obtainAccessibilityEvent(int virtualViewId, int eventType) {
if (BuildConfig.DEBUG && virtualViewId == ROOT_NODE_ID) {
Log.e(TAG, "VirtualView node must not be the root node.");
}
AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
event.setPackageName(rootAccessibilityView.getContext().getPackageName());
event.setSource(rootAccessibilityView, virtualViewId);
return event;
}
这里没什么特别的,它只在清单中设置的主活动上调用getPackageName()。 我什至在MainActivity上重写了getPackageName方法,以显式返回程序包名称,但这无济于事。 该软件包名称会发生什么?这是Flutter的错误,还是Android可以将其设置为服务时将其设置为null?我不知道。请指教,失去了很大的机会。