web-dev-qa-db-ja.com

ウィンドウを追加できません-トークン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 Android.os.BinderProxy@405180f8 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)

何か案が?

95
Han Tran

これは、存在しないコンテキストのダイアログを表示しているときに発生する可能性があります。一般的なケース-「ダイアログの表示」操作が非同期操作の後であり、その操作中に元のアクティビティ(つまり、ダイアログの親)が破棄される場合。適切な説明については、このブログ投稿とコメントを参照してください。

http://dimitar.me/Android-displaying-dialogs-from-background-threads/

上記のスタックトレースから、facebookライブラリはauth操作を非同期にスピンオフし、このシナリオを簡単に作成できるHandler-Callbackメカニズム(リスナーでonCompleteが呼び出される)があるように見えます。

これが私のアプリで報告されているのを見たとき、それは非常にまれであり、ブログ投稿の経験と一致します。 AsyncTaskの作業中に、アクティビティに問題が発生したか、破壊されました。あなたの変更が毎回どのようにこれを引き起こす可能性があるのか​​わかりませんが、おそらくあなたはコードの実行時に常に破壊されるダイアログのコンテキストとしてアクティビティを参照していますか?

また、これがアクティビティが実行されているかどうかを判断する最良の方法であるかどうかはわかりませんが、その方法の1つについては、この回答を参照してください。

アクティビティがアクティブかどうかを確認

110
Peter Pascale

一部のアプリからこのエラーがときどき報告されていましたが、ここで解決しました。

if(!((Activity) context).isFinishing())
{
    //show dialog
}

そこにある他のすべての答えは、実行中のアクティビティのリストを反復処理するなどの奇妙なことをしているように見えますが、これははるかに簡単で、トリックを行うようです。

134
DiscDev

1つの簡単な回避策は、例外をキャッチすることです。

try {
        alertDialog.show()
    }
catch (WindowManager.BadTokenException e) {
        //use a log message
    }

非同期操作を管理する必要があり、ダイアログを表示したいときにアクティビティが稼働しているかどうかがわからないときは、エレガントではありませんが、時には簡単です。

4
gerz

このWebサイト は、特定のActivityrunningであるかどうかを確認する3つの異なる方法をリストし、役立つコードスニペットを提供します。 。ただし、アクティビティがまだ実行中かどうかを確認することはデバッグのみに推奨されることを忘れないでください結果は確実ではないため、コード/ロジックフロー。

3
ACLima
  • 私の場合、onPostExecute AsyncTaskのダイアログボックスを開く/表示しようとするために問題が発生します。

  • ただし、showing dialogまたはUiの間違ったメソッドはonPostExecuteで変更されます。

  • そのため、アクティビティがアクティブになっていることを確認する必要がありますEg:!isFinishing()、アクティビティが終了していない場合は、ダイアログボックスまたはUIの変更のみを表示できます。

    @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());
                            }
                        }
                    }
                });
    }
    
2
Agilanbu

スレッドを実行した後、これらの2行のコードを追加すると、問題が解決します。

Looper.loop();
Looper.myLooper().quit();

私はまったく同じ問題に直面しました。 '(!isFinishing())'を呼び出してクラッシュを防止しましたが、「アラート」メッセージを表示できませんでした。

次に、アラートを表示する呼び出し関数'static'を作成してみました。その後、クラッシュは発生せず、メッセージも表示されます。

例:

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();      
    }
1
ArunJTS

私にとっては、DialogHelper.classメソッドのstaticプロパティ(ダイアログを作成および非表示にするための責任)を削除することで修正されました。これらのメソッドにはWindowに関連するプロパティがあります

0
Dasser Basyouni

DependencyServicesの下では、上記のいずれも私を助けませんでしたが、私は以下のようになりました:

    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);
        }
    }

インターフェイスを静的にすることはできないため、「double-class」を使用する必要があります。 L-

0
Legion