Logcat输出:
04-16 03:36:43.197: E/AndroIDRuntime(2465): FATAL EXCEPTION: main04-16 03:36:43.197: E/AndroIDRuntime(2465): Process: com.voIDstar.glass.sample.pinDrop,PID: 246504-16 03:36:43.197: E/AndroIDRuntime(2465): java.lang.RuntimeException: Unable to resume activity {com.voIDstar.glass.sample.pinDrop/com.voIDstar.glass.sample.pinDrop.MenuActivity}: androID.vIEw.WindowManager$BadTokenException: Unable to add window -- token null is not valID; is your activity running?04-16 03:36:43.197: E/AndroIDRuntime(2465): at androID.app.ActivityThread.performResumeActivity(ActivityThread.java:2828)04-16 03:36:43.197: E/AndroIDRuntime(2465): at androID.app.ActivityThread.handleResumeActivity(ActivityThread.java:2857)04-16 03:36:43.197: E/AndroIDRuntime(2465): at androID.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2290)04-16 03:36:43.197: E/AndroIDRuntime(2465): at androID.app.ActivityThread.access0(ActivityThread.java:138)04-16 03:36:43.197: E/AndroIDRuntime(2465): at androID.app.ActivityThread$H.handleMessage(ActivityThread.java:1236)04-16 03:36:43.197: E/AndroIDRuntime(2465): at androID.os.Handler.dispatchMessage(Handler.java:102)04-16 03:36:43.197: E/AndroIDRuntime(2465): at androID.os.Looper.loop(Looper.java:149)04-16 03:36:43.197: E/AndroIDRuntime(2465): at androID.app.ActivityThread.main(ActivityThread.java:5061)04-16 03:36:43.197: E/AndroIDRuntime(2465): at java.lang.reflect.Method.invokeNative(Native Method)04-16 03:36:43.197: E/AndroIDRuntime(2465): at java.lang.reflect.Method.invoke(Method.java:515)04-16 03:36:43.197: E/AndroIDRuntime(2465): at com.androID.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)04-16 03:36:43.197: E/AndroIDRuntime(2465): at com.androID.internal.os.ZygoteInit.main(ZygoteInit.java:610)04-16 03:36:43.197: E/AndroIDRuntime(2465): at dalvik.system.NativeStart.main(Native Method)04-16 03:36:43.197: E/AndroIDRuntime(2465): Caused by: androID.vIEw.WindowManager$BadTokenException: Unable to add window -- token null is not valID; is your activity running?04-16 03:36:43.197: E/AndroIDRuntime(2465): at androID.vIEw.VIEwRootImpl.setVIEw(VIEwRootImpl.java:561)04-16 03:36:43.197: E/AndroIDRuntime(2465): at androID.vIEw.WindowManagerGlobal.addVIEw(WindowManagerGlobal.java:259)04-16 03:36:43.197: E/AndroIDRuntime(2465): at androID.vIEw.WindowManagerImpl.addVIEw(WindowManagerImpl.java:69)04-16 03:36:43.197: E/AndroIDRuntime(2465): at com.androID.internal.policy.impl.PhoneWindow.openPanel(PhoneWindow.java:693)04-16 03:36:43.197: E/AndroIDRuntime(2465): at com.androID.internal.policy.impl.PhoneWindow.openPanel(PhoneWindow.java:555)04-16 03:36:43.197: E/AndroIDRuntime(2465): at androID.app.Activity.openoptionsMenu(Activity.java:2878)04-16 03:36:43.197: E/AndroIDRuntime(2465): at com.voIDstar.glass.sample.pinDrop.MenuActivity.onResume(MenuActivity.java:71)04-16 03:36:43.197: E/AndroIDRuntime(2465): at androID.app.Instrumentation.callActivityOnResume(Instrumentation.java:1194)04-16 03:36:43.197: E/AndroIDRuntime(2465): at androID.app.Activity.performResume(Activity.java:5316)04-16 03:36:43.197: E/AndroIDRuntime(2465): at androID.app.ActivityThread.performResumeActivity(ActivityThread.java:2818)04-16 03:36:43.197: E/AndroIDRuntime(2465): ... 12 more
服务中将活动绑定到live Card的方法:
@OverrIDe public int onStartCommand(Intent intent,int flags,int startID) { // This method is called whenever the Glassware is invoked via voice commands or the OK Glass menu. if (mliveCard == null) { Log.d(TAG,"Connecting mLocationManager"); Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_COARSE); PinDropLocationListener Listener = new PinDropLocationListener(); locationListeners.add(Listener); mLocationManager.requestSingleUpdate(criteria,Listener,null); mliveCard = new liveCard(getBaseContext(),liVE_CARD_TAG); mliveCard.setVIEws(new RemoteVIEws(getPackagename(),R.layout.activity_waiting)); mliveCard.attach(this); // Prevent this Service from being killed to free up memory Intent menuIntent = new Intent(this,MenuActivity.class); // Since menus can only be attached to ActivitIEs,we create an activity to own and launch the menu. menuIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); mliveCard.setAction(PendingIntent.getActivity(this,menuIntent,0)); // This Intent will be fired whenever the liveCard is tapped. Log.d(TAG,"Publishing liveCard"); mliveCard.publish(PublishMode.REVEAL); // Add the liveCard to the Timeline and switch to it Log.d(TAG,"Done publishing liveCard"); } else { mliveCard.navigate(); // Switch to the app if it's already running } return START_STICKY; // No IDea what this does. Your guess is as good as mine. }
而有问题的活动:
/** * Activity showing the options menu. */public class MenuActivity extends Activity { // This is technically an Immersion! // Because Services have no UI,we need to open this Activity,which in turn opens its menu! PinDropService.MenuBinder mBinder; private static String TAG = "PinDropMenu"; boolean hasLocation; /* * links this Activity to the Service that spawned it,so the Menu can send and receive information */ private ServiceConnection mConnection = new ServiceConnection() { @OverrIDe public voID onServiceConnected(Componentname name,IBinder service) { if (service instanceof PinDropService.MenuBinder) { mBinder = (PinDropService.MenuBinder)service; hasLocation = mBinder.hasLocation(); Log.d(TAG,hasLocation ? "Received has location" : "Received no location"); //openoptionsMenu(); } } @OverrIDe public voID onServicedisconnected(Componentname name) {} }; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); bindService(new Intent(this,PinDropService.class),mConnection,0); } @OverrIDe public voID onResume() { super.onResume(); openoptionsMenu(); } @OverrIDe public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.pindropmenu,menu); return true; } @OverrIDe public boolean onPrepareOptionsMenu(Menu menu) { if (!hasLocation) { menu.findItem(R.ID.directions).setVisible(false); menu.findItem(R.ID.remember).setVisible(false); } else { menu.findItem(R.ID.directions).setVisible(true); menu.findItem(R.ID.remember).setVisible(true); } return true; } @OverrIDe public boolean onoptionsItemSelected(MenuItem item) { // Handle item selection. switch (item.getItemID()) { case R.ID.directions: mBinder.startNavigation(); return true; case R.ID.remember: mBinder.addToTimeline(); // Todo: Add Mirror functionality! return true; case R.ID.stop: // IT IS CRITICALLY important TO ADD THIS OR THE GLASSWARE CAN'T BE KILLED IN USERSPACE! stopService(new Intent(this,PinDropService.class)); return true; default: return super.onoptionsItemSelected(item); } } @OverrIDe public voID onoptionsMenuClosed(Menu menu) { // nothing else to do,closing the Activity. finish(); } @OverrIDe public voID onStop() { super.onStop(); unbindService(mConnection); // Don't leak Services! }}
点击live Card会导致立即崩溃,并且上面的Logcat输出被转储.奇怪的是,如果注释掉的openoptionsMenu()被取消注释并且现有的openoptionsMenu()被注释掉,则第一次点击将实际打开菜单.打开菜单的第二次尝试将失败,具有类似的Logcat输出(BadTokenException是主要异常,而不是RuntimeException上的内部异常).
解决方法 As petey said,但除了onResume()之外,还需要覆盖onAttachedToWindow().我的代码现在看起来像:private boolean isAttached = false;@OverrIDepublic voID onAttachedToWindow() { super.onAttachedToWindow(); this.isAttached = true; openoptionsMenu();}@OverrIDepublic voID onResume() { super.onResume(); if (this.isAttached) openoptionsMenu();}总结
以上是内存溢出为你收集整理的android – 在XE16中调用openOptionsMenu()会导致WindowManager.BadTokenException全部内容,希望文章能够帮你解决android – 在XE16中调用openOptionsMenu()会导致WindowManager.BadTokenException所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)