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?
Jawaban:
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
sumber
dialog.show()
memecahkan masalah tetapi apa solusi untuk tetap dapat menampilkan dialog saya?Fragment.getContext()
, yang berfungsi untuk API di atas 21. Tetapi di Lollipop, crashSaya melihat kesalahan ini dilaporkan sesekali dari beberapa aplikasi saya, dan inilah yang memecahkannya untuk saya:
Semua jawaban lain di luar sana tampaknya melakukan hal-hal aneh seperti mengulang daftar aktivitas berlari, tetapi ini jauh lebih sederhana dan tampaknya berhasil.
sumber
context instanceof Activity
atau Anda mungkin mendapatkanException
!satu solusi sederhana adalah menangkap pengecualian:
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.
sumber
Dalam kasus saya, masalah ini terjadi karena saya mencoba membuka / menampilkan kotak dialog di
onPostExecute
AsyncTaskNamun itu adalah metode yang salah
showing dialog
atau Ui berubahonPostExecute
.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.sumber
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:
sumber
Setelah menjalankan utas, tambahkan dua baris kode ini, dan itu akan menyelesaikan masalah.
sumber
Kasus penggunaan pengembang lain: Jika
WindowManager
ataugetWindow()
sedang dipanggilonCreate()
atauonStart()
atauonResume()
, aBadTokenException
dilemparkan. 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().screenBrightness
dionResume()
menghasilkan pengecualian. Memindahkan kode agaronAttachedToWindow()
berfungsi.sumber
Bagi saya itu diperbaiki dengan hanya menghapus
static
properti di metode DialogHelper.class (bertanggung jawab untuk membuat & menyembunyikan dialog), karena saya memiliki properti yang terkait denganWindow
metode tersebutsumber
Di bawah dependencyServices tidak ada hal di atas yang membantu saya, saya akhirnya melakukan seperti di bawah ini:
Saya harus menggunakan "kelas ganda" karena antarmuka tidak boleh statis. L-
sumber
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?
sumber
Saya menyelesaikannya dengan meletakkan ini:
sumber