Не удалось добавить оконный токен android.os.BinderProxy недействителен; работает ли ваша деятельность?
Я пытаюсь подключиться к Facebook через API Facebook, я следую этому примеру: https://github.com/facebook/facebook-android-sdk/tree/master/examples/simple
Все в порядке, но когда я пытаюсь отредактировать какой-либо код, я имею в виду, что хочу отобразить сообщение с диалоговым сообщением после успешного входа в систему:
public void onAuthSucceed() {
mText.setText("You have logged in! ");
//This is the code to call the post message dialog.
mFacebook.dialog(Example.this, "feed",new SampleDialogListener());
}
Я получаю эту ошибку в logcat:
03-02 13:32:08.629: E/AndroidRuntime(14991): android.view.WindowManager$BadTokenException: Unable to add window -- token [email protected] is not valid; is your activity running?
03-02 13:32:08.629: E/AndroidRuntime(14991): at android.view.ViewRoot.setView(ViewRoot.java:532)
03-02 13:32:08.629: E/AndroidRuntime(14991): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
03-02 13:32:08.629: E/AndroidRuntime(14991): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
03-02 13:32:08.629: E/AndroidRuntime(14991): at android.view.Window$LocalWindowManager.addView(Window.java:424)
03-02 13:32:08.629: E/AndroidRuntime(14991): at android.app.Dialog.show(Dialog.java:241)
03-02 13:32:08.629: E/AndroidRuntime(14991): at com.facebook.android.Facebook.dialog(Facebook.java:780)
03-02 13:32:08.629: E/AndroidRuntime(14991): at com.facebook.android.Facebook.dialog(Facebook.java:737)
03-02 13:32:08.629: E/AndroidRuntime(14991): at com.facebook.android.Example$SampleAuthListener.onAuthSucceed(Example.java:113)
03-02 13:32:08.629: E/AndroidRuntime(14991): at com.facebook.android.SessionEvents.onLoginSuccess(SessionEvents.java:78)
03-02 13:32:08.629: E/AndroidRuntime(14991): at com.facebook.android.Example$LoginDialogListener.onComplete(Example.java:88)
03-02 13:32:08.629: E/AndroidRuntime(14991): at com.facebook.android.Facebook$1.onComplete(Facebook.java:320)
03-02 13:32:08.629: E/AndroidRuntime(14991): at com.facebook.android.FbDialog$FbWebViewClient.shouldOverrideUrlLoading(FbDialog.java:144)
03-02 13:32:08.629: E/AndroidRuntime(14991): at android.webkit.CallbackProxy.uiOverrideUrlLoading(CallbackProxy.java:218)
03-02 13:32:08.629: E/AndroidRuntime(14991): at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:337)
03-02 13:32:08.629: E/AndroidRuntime(14991): at android.os.Handler.dispatchMessage(Handler.java:99)
03-02 13:32:08.629: E/AndroidRuntime(14991): at android.os.Looper.loop(Looper.java:130)
03-02 13:32:08.629: E/AndroidRuntime(14991): at android.app.ActivityThread.main(ActivityThread.java:3687)
03-02 13:32:08.629: E/AndroidRuntime(14991): at java.lang.reflect.Method.invokeNative(Native Method)
03-02 13:32:08.629: E/AndroidRuntime(14991): at java.lang.reflect.Method.invoke(Method.java:507)
03-02 13:32:08.629: E/AndroidRuntime(14991): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
03-02 13:32:08.629: E/AndroidRuntime(14991): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
03-02 13:32:08.629: E/AndroidRuntime(14991): at dalvik.system.NativeStart.main(Native Method)
Любая идея?
Ответы
Ответ 1
Это может произойти, когда вы показываете диалог для контекста, который больше не существует. Обычный случай - если операция "показать диалог" после асинхронной операции, и во время этой операции исходное действие (то есть должно быть родителем вашего диалога) уничтожено. Для хорошего описания см. Это сообщение в блоге и комментарии:
http://dimitar.me/android-displaying-dialogs-from-background-threads/
Из вышеприведенной трассировки стека кажется, что библиотека facebook асинхронно отключает аут-операцию, и у вас есть механизм Handler-Callback (onComplete, вызываемый слушателем), который может легко создать этот сценарий.
Когда я видел это в своем приложении, его довольно редко и соответствует опыту в блоге. Что-то пошло не так для деятельности/оно было разрушено во время работы AsyncTask. Я не знаю, как ваша модификация может привести к этому каждый раз, но, возможно, вы ссылаетесь на Activity как на контекст для диалога, который всегда уничтожается ко времени выполнения вашего кода?
Кроме того, хотя я не уверен, что это лучший способ узнать, работает ли ваша активность, см. этот ответ для одного метода:
Проверьте, активна ли активность
Ответ 2
Я видел, что эта ошибка сообщалась раз в то время из некоторых моих приложений, и вот что решило это для меня:
if(!((Activity) context).isFinishing())
{
//show dialog
}
Все остальные ответы там, кажется, делают странные вещи, такие как повторение списка запущенных действий, но это намного проще и, похоже, делает трюк.
Ответ 3
Один простой обходной путь - поймать исключение:
try {
alertDialog.show()
}
catch (WindowManager.BadTokenException e) {
//use a log message
}
Это не элегантно, но иногда легко, когда вам нужно управлять асинхронными операциями, и вы не уверены, активна ли активность или нет, когда вы хотите показать диалоговое окно.
Ответ 4
На этом веб-сайте перечислены 3 различных метода проверки, если определенный Activity
работает, и предоставляет фрагменты кода для помочь тебе. Однако имейте в виду, что проверка того, что активность еще выполняется, предназначена только для отладки, поскольку ее результат не является чем-то конкретным и, следовательно, не подходит для потока кода/логики.
Ответ 5
-
В моем случае проблема возникает из-за того, что я пытаюсь открыть/показать диалоговое окно в onPostExecute
AsyncTask
-
Однако это неправильный метод showing dialog
или изменений пользовательского onPostExecute
в onPostExecute
.
-
Для этого нам нужно проверить, что активность активна. Например !isFinishing()
, если операция не завершена, то мы можем показать только наше диалоговое окно или изменение пользовательского интерфейса.
@Override
protected void onPostExecute(String response_str) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (!((Activity) mContext).isFinishing()) {
try {
ShowAgilDialog();
} catch (WindowManager.BadTokenException e) {
Log.e("WindowManagerBad ", e.toString());
}
}
}
});
}
Ответ 6
Я столкнулся с такой же проблемой. Вызов '(!isFinishing())'
предотвратил сбой, но не смог отобразить сообщение "alert".
Затем я попытался сделать функцию вызова 'static', где отображается предупреждение. После этого не произошло сбоя, и сообщение также отображается.
Для ex:
public static void connect_failure() {
Log.i(FW_UPD_APP, "Connect failed");
new AlertDialog.Builder(MyActivity)
.setTitle("Title")
.setMessage("Message")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//do nothing
}
})
.setIcon(R.drawable.the_image).show();
}
Ответ 7
После выполнения потока добавьте эти две строки кода, и это решит проблему.
Looper.loop();
Looper.myLooper().quit();
Ответ 8
Для меня это было исправлено простым удалением static
свойства в методах DialogHelper.class(resposble для создания и скрытия диалога), так как у меня есть свойства, связанные с Window
в этих методах
Ответ 9
В зависимости от услуг ничего из вышеперечисленного не помогло мне, в итоге я сделал следующее:
class Static_Toast_Android
{
private static Context _context
{
get { return Android.App.Application.Context; }
}
public static void StaticDisplayToast(string message)
{
Toast.MakeText(_context, message, ToastLength.Long).Show();
}
}
public class Toast_Android : IToast
{
public void DisplayToast(string message)
{
Static_Toast_Android.StaticDisplayToast(message);
}
}
Я должен использовать "двойной класс", потому что интерфейс не может быть статическим.
L-