XE12'de iyi çalışan bir GDK uygulamasına sahibim, ancak şimdi XE16'da GDK'ya geçtikten sonra çöküyor: 19. Özellikle, bir Etkinlikte openOptionsMenu()
'u çağırmak (bu durumda, Canlı Kartta bir seçenekler menüsünü açmak için), BadTokenExceptions'a neden olur.XE16'da openOptionsMenu() işlevi neden oluyor WindowManager.BadTokenException
Logcat çıkışı: Hizmet
04-16 03:36:43.197: E/AndroidRuntime(2465): FATAL EXCEPTION: main
04-16 03:36:43.197: E/AndroidRuntime(2465): Process: com.voidstar.glass.sample.pinDrop, PID: 2465
04-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.access$800(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
Yöntem Canlı Karta Aktivite bağlar:
@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, 0, 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.
}
Ve sorunlu Aktivite: Canlı Kart nedenlerini dokunulduğunda
/**
* 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!
}
}
Hemen bir kilitlenme ve yukarıdaki Logcat çıkışı boşaltıldı. Garip olan şey, eğer yorumlanmış openOptionsMenu() ifadesi kaldırılırsa ve mevcut openOptionsMenu() yorumlanırsa, ilk dokunma aslında menüyü açar. Menüyü açmaya yönelik ikinci deneme, benzer Logcat çıktısı ile başarısız olur (BadTokenException, RuntimeException'daki bir iç özel durum yerine ana kural dışı durumdur).
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
mAttachedToWindow = true;
openOptionsMenu();
}
TY dario: - skylight1 içinde Dario'ya