ไม่สามารถเพิ่มหน้าต่าง - โทเค็น android.os.BinderProxy ไม่ถูกต้อง กิจกรรมของคุณกำลังดำเนินอยู่หรือไม่


116

ฉันพยายามเชื่อมต่อกับ Facebook ผ่าน Facebook API ฉันทำตามตัวอย่างนี้: 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)

ความคิดใด ๆ ?


อาจเกิดข้อผิดพลาด
bsara

1
ตรวจสอบคำตอบด้านล่าง ฉันทำเครื่องหมายว่าถูกต้อง :)
Han Tran

เพียงเพราะคุณทำเครื่องหมายคำตอบไม่ได้เปลี่ยนความจริงที่ว่านี่เป็นคำถามที่ซ้ำกัน อีกฝ่ายถูกถามก่อนและเป็นปัญหาที่เหมือนกันโดยมีคำตอบที่เหมือนกันเป็นหลัก
bsara

1
คุณเห็นไหมว่าคำถามของฉันเมื่อ 2 ปีที่แล้ว?
Han Tran

1
ดูเหมือนว่าคนอื่น ๆ โมเดอเรเตอร์มีข้อผิดพลาด แต่คุณ :)) ขอบคุณ!
Han Tran

คำตอบ:


127

สิ่งนี้สามารถเกิดขึ้นได้เมื่อคุณกำลังแสดงกล่องโต้ตอบสำหรับบริบทที่ไม่มีอยู่แล้ว กรณีทั่วไป - ถ้าการดำเนินการ 'แสดงกล่องโต้ตอบ' อยู่หลังการดำเนินการแบบอะซิงโครนัสและในระหว่างการดำเนินการนั้นกิจกรรมดั้งเดิม (ซึ่งจะเป็นพาเรนต์ของไดอะล็อกของคุณ) จะถูกทำลาย สำหรับคำอธิบายที่ดีโปรดดูโพสต์บล็อกและความคิดเห็นนี้:

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

จากการติดตามสแต็กด้านบนดูเหมือนว่าไลบรารี facebook จะหมุนการดำเนินการรับรองความถูกต้องแบบอะซิงโครนัสและคุณมีกลไก Handler - Callback (onComplete เรียกบนเครื่องฟัง) ที่สามารถสร้างสถานการณ์นี้ได้อย่างง่ายดาย

เมื่อฉันเห็นสิ่งนี้รายงานในแอปของฉันมันค่อนข้างหายากและตรงกับประสบการณ์ในบล็อกโพสต์ เกิดข้อผิดพลาดในกิจกรรม / กิจกรรมนี้ถูกทำลายระหว่างการทำงานของ AsyncTask ฉันไม่รู้ว่าการแก้ไขของคุณจะส่งผลอย่างไรในทุกครั้ง แต่บางทีคุณอาจอ้างถึงกิจกรรมเป็นบริบทของกล่องโต้ตอบที่มักจะถูกทำลายตามเวลาที่โค้ดของคุณดำเนินการอยู่เสมอ?

นอกจากนี้ในขณะที่ฉันไม่แน่ใจว่านี่เป็นวิธีที่ดีที่สุดในการตรวจสอบว่ากิจกรรมของคุณกำลังดำเนินอยู่หรือไม่โปรดดูคำตอบนี้สำหรับวิธีการเดียว:

ตรวจสอบว่ามีกิจกรรมอยู่หรือไม่


3
การไม่โทรdialog.show()ช่วยแก้ปัญหา แต่จะมีวิธีแก้ไขอย่างไรเพื่อให้ยังคงแสดงกล่องโต้ตอบของฉันได้
natsumiyu

สำหรับฉันฉันกำลังโทรหาFragment.getContext()ซึ่งใช้ได้กับ API ที่สูงกว่า 21 แต่ใน Lollipop มันขัดข้อง
TheRealChx101

158

ฉันเห็นข้อผิดพลาดนี้รายงานเป็นครั้งคราวจากแอพบางตัวของฉันและนี่คือสิ่งที่แก้ไขได้สำหรับฉัน:

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

คำตอบอื่น ๆ ทั้งหมดดูเหมือนจะทำสิ่งแปลก ๆ เช่นการทำซ้ำในรายการกิจกรรมการวิ่ง แต่นี่ง่ายกว่ามากและดูเหมือนจะทำเคล็ดลับ


6
มันไม่สามารถแก้ปัญหาได้ แต่ป้องกันความผิดพลาดและการแสดงกล่องโต้ตอบด้วย
YTerle

6
เพียงจำไว้ว่าคุณควรตรวจสอบมิcontext instanceof Activityฉะนั้นคุณอาจได้รับException!
FtheBuilder

3
หรือคุณสามารถใช้ getActivity (). isFinishing () แทนบริบท
Nikita Axyonov

ฉันใช้ API-23 เมื่อฉันพยายามใช้สิ่งนี้ใน MainActivity ของฉันซึ่งขยาย AppCompatActivity มันแสดงให้ฉันเห็นข้อผิดพลาดเช่นเกิดจาก: java.lang.ClassCastException: com.creativeapp.hindihdvideosongs.AppController ไม่สามารถส่งไปยัง android.app.Activity ที่ com.creativeapp.hindihdvideosongs.MainActivity.onCreate (MainActivity.java:145) AppController คือ เพิ่มเข้าไปใน AndroidMenifest ของฉัน
พาเวล

ฉันไม่ได้ใช้บทสนทนาใด ๆ และได้รับข้อผิดพลาดนี้
อับดุลวาเฮด

11

วิธีแก้ปัญหาง่ายๆอย่างหนึ่งคือการจับข้อยกเว้น:

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

มันไม่สวยหรู แต่บางครั้งก็ง่ายเมื่อคุณต้องจัดการการทำงานแบบ async และคุณไม่แน่ใจว่ากิจกรรม wether จะเปิดขึ้นหรือไม่เมื่อคุณต้องการแสดงกล่องโต้ตอบ


1
น่าเกลียด แต่สวยมาก!
Rahul Tiwari

8
  • ในกรณีของฉันปัญหาเกิดขึ้นเนื่องจากฉันพยายามเปิด / แสดงกล่องโต้ตอบในonPostExecuteAsyncTask

  • แต่วิธีการที่ไม่ถูกต้องของหรืออุ้ยเปลี่ยนแปลงshowing dialogonPostExecute

  • สำหรับสิ่งนั้นเราจำเป็นต้องตรวจสอบว่ากิจกรรมนั้นอยู่ในสถานะใช้งานอยู่เช่น !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());
                            }
                        }
                    }
                });
    }

1

ฉันประสบปัญหาเดียวกันทุกประการ โทร'(!isFinishing())'ป้องกันความผิดพลาด แต่ไม่สามารถแสดงข้อความ "แจ้งเตือน" ได้

จากนั้นฉันลองสร้างฟังก์ชันการโทร'คงที่'ซึ่งการแจ้งเตือนจะปรากฏขึ้น หลังจากนั้นจะไม่มีข้อขัดข้องเกิดขึ้นและข้อความจะแสดงขึ้นด้วย

สำหรับเช่น:

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

กรณีการใช้งานของนักพัฒนารายอื่น: หากWindowManagerหรือgetWindow()ถูกเรียกใช้onCreate()หรือonStart()หรือonResume()BadTokenExceptionถูกโยนทิ้ง คุณจะต้องรอจนกว่ามุมมองจะถูกจัดเตรียมและแนบมา

ย้ายรหัสไปที่ onAttachedToWindow()แก้ปัญหา อาจไม่ใช่วิธีแก้ปัญหาถาวร แต่เท่าที่ฉันทดสอบได้มันก็ใช้ได้เสมอ

ในกรณีของฉันจำเป็นต้องเพิ่มความสว่างของหน้าจอเมื่อมองเห็นกิจกรรมได้ บรรทัดgetWindow().getAttributes().screenBrightnessในonResume()ผลลัพธ์เป็นข้อยกเว้น ย้ายรหัสไปonAttachedToWindow()ทำงาน


0

สำหรับฉันมันได้รับการแก้ไขโดยเพียงแค่ลบstaticคุณสมบัติในเมธอด DialogHelper.class (ตอบสนองสำหรับการสร้างและซ่อนไดอะล็อก) เนื่องจากฉันมีคุณสมบัติที่เกี่ยวข้องกับWindowเมธอดเหล่านั้น


0

ภายใต้การพึ่งพาบริการไม่มีสิ่งใดจากข้างต้นที่ช่วยฉันได้ฉันทำดังนี้:

    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

ไม่สามารถเพิ่มหน้าต่าง - โทเค็นไม่ถูกต้อง กิจกรรมของคุณกำลังดำเนินอยู่หรือไม่

ข้อขัดข้องนี้มักเกิดจากแอปของคุณพยายามแสดงกล่องโต้ตอบโดยใช้กิจกรรมที่ทำเสร็จก่อนหน้านี้เป็นบริบท ตัวอย่างเช่นกรณีนี้อาจเกิดขึ้นได้หากกิจกรรมทริกเกอร์ AsyncTask ที่พยายามแสดงกล่องโต้ตอบเมื่อเสร็จสิ้น แต่ผู้ใช้กลับจากกิจกรรมก่อนที่งานจะเสร็จสมบูรณ์

แหล่งข้อมูลภายนอก

Android - การแสดงกล่องโต้ตอบจากเธรดพื้นหลัง

ข้อผิดพลาด: BinderProxy @ 45d459c0 ไม่ถูกต้อง กิจกรรมของคุณกำลังดำเนินอยู่หรือไม่


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.