Tidak dapat menambahkan jendela - token android.os.BinderProxy tidak valid; apakah aktivitasmu sedang berjalan?

116

Saya mencoba untuk terhubung ke Facebook melalui Facebook API, saya mengikuti contoh ini: https://github.com/facebook/facebook-android-sdk/tree/master/examples/simple

Semuanya baik-baik saja, tetapi ketika saya mencoba mengedit beberapa kode, maksud saya saya ingin menampilkan pesan posting dialog setelah login berhasil seperti ini:

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

Saya menerima kesalahan ini di 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)

Ada ide?

Han Tran
sumber
1
Cek jawabannya di bawah ini. Saya sudah tandai itu benar :)
Han Tran
Hanya karena Anda telah menandai jawabannya tidak mengubah fakta bahwa ini adalah pertanyaan duplikat. Yang lain ditanya terlebih dahulu dan merupakan masalah yang identik dengan jawaban yang pada dasarnya identik.
bsara
1
Apakah Anda melihat bahwa pertanyaan saya adalah 2 tahun yang lalu?
Han Tran
1
Jadi sepertinya Moderator lain melakukan kesalahan tetapi Anda :)) Anw, terima kasih!
Han Tran

Jawaban:

127

Ini bisa terjadi saat Anda menampilkan dialog untuk konteks yang sudah tidak ada. Kasus umum - jika operasi 'show dialog' terjadi setelah operasi asinkron, dan selama operasi tersebut aktivitas asli (yang akan menjadi induk dari dialog Anda) dimusnahkan. Untuk deskripsi yang bagus, lihat posting blog dan komentar ini:

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

Dari pelacakan tumpukan di atas, tampaknya pustaka facebook memutar operasi autentikasi secara asinkron, dan Anda memiliki mekanisme Handler - Callback (onComplete dipanggil pada pendengar) yang dapat dengan mudah membuat skenario ini.

Ketika saya telah melihat ini dilaporkan di aplikasi saya, ini cukup langka dan cocok dengan pengalaman di posting blog. Ada yang tidak beres untuk aktivitas / aktivitas itu hancur selama pengerjaan AsyncTask. Saya tidak tahu bagaimana modifikasi Anda dapat menghasilkan hal ini setiap saat, tetapi mungkin Anda merujuk pada Aktivitas sebagai konteks dialog yang selalu dihancurkan pada saat kode Anda dijalankan?

Selain itu, meskipun saya tidak yakin apakah ini cara terbaik untuk mengetahui apakah aktivitas Anda sedang berjalan, lihat jawaban ini untuk salah satu metode melakukannya:

Periksa apakah aktivitas aktif

Peter Pascale
sumber
3
Tidak menelepon dialog.show()memecahkan masalah tetapi apa solusi untuk tetap dapat menampilkan dialog saya?
natsumiyu
Bagi saya, saya menelepon Fragment.getContext(), yang berfungsi untuk API di atas 21. Tetapi di Lollipop, crash
TheRealChx101
158

Saya melihat kesalahan ini dilaporkan sesekali dari beberapa aplikasi saya, dan inilah yang memecahkannya untuk saya:

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

Semua jawaban lain di luar sana tampaknya melakukan hal-hal aneh seperti mengulang daftar aktivitas berlari, tetapi ini jauh lebih sederhana dan tampaknya berhasil.

DiscDev
sumber
6
itu tidak menyelesaikan masalah, itu mencegah crash dan menampilkan dialog juga
YTerle
6
Ingat saja Anda harus memeriksa context instanceof Activityatau Anda mungkin mendapatkan Exception!
FtheBuilder
3
atau Anda dapat menggunakan getActivity (). isFinishing () alih-alih konteks
Nikita Axyonov
Saya menggunakan API-23. Saat saya mencoba menggunakan ini di MainActivity yang memperluas AppCompatActivity. Itu menunjukkan kepada saya kesalahan seperti Disebabkan oleh: java.lang.ClassCastException: com.creativeapp.hindihdvideosongs.AppController tidak dapat dilemparkan ke android.app.Activity di com.creativeapp.hindihdvideosongs.MainActivity.onCreate (MainActivity.java:145) AppController ditambahkan ke AndroidMenifest saya
pavel
Saya tidak menggunakan dialog apa pun dan mendapatkan kesalahan ini.
Abdul Waheed
11

satu solusi sederhana adalah menangkap pengecualian:

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

Ini tidak elegan tetapi terkadang mudah ketika Anda harus mengelola operasi asinkron dan Anda tidak yakin apakah aktivitas sudah aktif atau tidak ketika Anda ingin menampilkan dialog.

gerz
sumber
1
sangat jelek namun sangat cantik!
Rahul Tiwari
8
  • Dalam kasus saya, masalah ini terjadi karena saya mencoba membuka / menampilkan kotak dialog di onPostExecuteAsyncTask

  • Namun itu adalah metode yang salah showing dialogatau Ui berubah onPostExecute.

  • Untuk itu perlu dicek bahwa aktivitas tersebut dalam keadaan aktif. Misal: !isFinishing() jika aktivitas belum selesai maka hanya dapat menampilkan kotak dialog atau ui berubah.

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

Saya menghadapi masalah yang persis sama. Panggilan '(!isFinishing())'mencegah crash, tapi tidak bisa menampilkan pesan 'alert'.

Kemudian saya mencoba membuat fungsi panggilan 'statis' , di mana peringatan ditampilkan. Setelah itu, tidak ada kerusakan yang terjadi dan pesan juga ditampilkan.

Misalnya:

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

Setelah menjalankan utas, tambahkan dua baris kode ini, dan itu akan menyelesaikan masalah.

Looper.loop();
Looper.myLooper().quit();
Balachandran Muthuraj
sumber
1

Kasus penggunaan pengembang lain: Jika WindowManageratau getWindow()sedang dipanggil onCreate()atau onStart()atau onResume(), a BadTokenExceptiondilemparkan. Anda harus menunggu hingga tampilan disiapkan dan dilampirkan.

Memindahkan kode untuk onAttachedToWindow()menyelesaikannya. Ini mungkin bukan solusi permanen, tetapi sebanyak yang bisa saya uji, itu selalu berhasil.

Dalam kasus saya, ada kebutuhan untuk meningkatkan kecerahan layar saat aktivitas menjadi terlihat. Baris getWindow().getAttributes().screenBrightnessdi onResume()menghasilkan pengecualian. Memindahkan kode agar onAttachedToWindow()berfungsi.

Ram Iyer
sumber
0

Bagi saya itu diperbaiki dengan hanya menghapus staticproperti di metode DialogHelper.class (bertanggung jawab untuk membuat & menyembunyikan dialog), karena saya memiliki properti yang terkait dengan Windowmetode tersebut

Dasser Basyouni
sumber
0

Di bawah dependencyServices tidak ada hal di atas yang membantu saya, saya akhirnya melakukan seperti di bawah ini:

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

Saya harus menggunakan "kelas ganda" karena antarmuka tidak boleh statis. L-

Pasukan
sumber
0

Tidak dapat menambahkan jendela - token tidak valid; apakah aktivitasmu sedang berjalan?

Error ini biasanya disebabkan oleh aplikasi Anda yang mencoba menampilkan dialog menggunakan Aktivitas yang sudah selesai sebelumnya sebagai konteks. Misalnya, ini bisa terjadi jika Aktivitas memicu AsyncTask yang mencoba menampilkan dialog saat selesai, tetapi pengguna menavigasi kembali dari Aktivitas sebelum tugas selesai.

Sumber daya eksternal

Android - Menampilkan Dialog Dari Thread Latar Belakang

Kesalahan: BinderProxy @ 45d459c0 tidak valid; apakah aktivitasmu sedang berjalan?

Bholendra Singh
sumber
0

Saya menyelesaikannya dengan meletakkan ini:

@Override
protected void onDestroy() {
    accessTokenTracker.stopTracking();
    super.onDestroy();
}
Juan L. Antón Santamaria
sumber
Silakan, pilih bahasa Inggris saat memposting
Pedro Coelho