ত্রুটি: বাইন্ডারপ্রক্সি @ 45d459c0 বৈধ নয়; আপনার কার্যক্রম চলছে?


143

এই ত্রুটিটি কী ... আমি স্ট্যাকওভারফ্লো সম্প্রদায়টিতে এই ত্রুটি সম্পর্কিত কোনও আলোচনা খুঁজে পাইনি বিশদ: -

10-18 23:53:11.613: ERROR/AndroidRuntime(3197): Uncaught handler: thread main exiting due to uncaught exception
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@45d459c0 is not valid; is your activity running?
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.view.ViewRoot.setView(ViewRoot.java:468)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.view.Window$LocalWindowManager.addView(Window.java:424)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.app.Dialog.show(Dialog.java:239)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at com.vishal.contacte.Locationlistener$MyLocationListener.onLocationChanged(Locationlistener.java:86)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.location.LocationManager$ListenerTransport._handleMessage(LocationManager.java:179)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.location.LocationManager$ListenerTransport.access$000(LocationManager.java:112)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.location.LocationManager$ListenerTransport$1.handleMessage(LocationManager.java:128)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.os.Looper.loop(Looper.java:123)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.app.ActivityThread.main(ActivityThread.java:4363)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at java.lang.reflect.Method.invokeNative(Native Method)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at java.lang.reflect.Method.invoke(Method.java:521)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:862)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at dalvik.system.NativeStart.main(Native Method)

এই লিঙ্কে চেক করুন: অ্যান্ড্রয়েড - [ব্যাকগ্রাউন্ড থ্রেডের থেকে ডায়ালগ প্রদর্শনের] ( dimitar.me/android-displaying-dialogs-from-background-threads )
নবীন

আপনার লিঙ্কটি গৃহীত উত্তরের অনুরূপ, তবে এটি আরও ভালভাবে শেষ হয়ে গেছে। তার জন্য ধন্যবাদ
লাকিমালাকা


উত্তর:


343

এটি সম্ভবত ঘটছে কারণ আপনি ব্যাকগ্রাউন্ড থ্রেড কার্যকর করার পরে একটি কথোপকথন দেখানোর চেষ্টা করছেন, যখন কার্যকলাপটি নষ্ট হচ্ছে is

আমার কিছু অ্যাপ্লিকেশন থেকে একবারে এই ত্রুটিটি প্রতিবেদন করা দেখছিলাম যখন ডায়ালগটি দেখানোর চেষ্টা করার সময় ডায়ালগটি কল করার ক্রিয়াকলাপটি কোনও কারণে বা অন্য কোনও কারণে শেষ হয়। এটি আমার জন্য কী সমাধান করেছে তা এখানে:

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

আমি বেশ কয়েক বছর ধরে অ্যান্ড্রয়েডের পুরানো সংস্করণগুলিতে ইস্যুটি নিয়ে কাজ করার জন্য এটি ব্যবহার করছি এবং এর পরে ক্রাশটি দেখিনি।


1
এটি আসলে কৌতুক করে! তবে ডায়ালগটি খোলার কোনও উপায় কি যদি তা হয় তবে? ডায়ালগটি কীভাবে পরিচালনা করা যায় তা সম্পর্কে আমি সত্যিই নিশ্চিত নই। কোনও পরামর্শ? আগাম ধন্যবাদ!
কারলা ওরিয়া স্ট্যাবিল

নিবন্ধন করুন এটি ঘটতে পারে এমন ডায়লগটি দেখানোর জন্য কেবলমাত্র আমি ভাবতে পারি যে আপনি যদি এমন কোনও ক্রিয়াকলাপের জন্য কোনও বৈধ প্রসঙ্গ গ্রহণ করতে পারেন যা শেষ না হয় - এটি নির্ভর করবে আপনি এই কোডটি কোথায় কল করছেন এবং যদি আপনার কোনও পুনরুদ্ধার করার উপায় রয়েছে অন্যের প্রসঙ্গ, সমাপ্তি না করা ক্রিয়াকলাপ।
ডিসকদেভ

8
অসংখ্য ধন্যবাদ! ডায়ালগ বক্সটি দেখানোর আগে আমি যখন পিছনের বোতামটি টিপতাম তখন আমার জন্য ক্র্যাশ (উপরে ত্রুটির বার্তা সহ) ঘটতে পারে। সুতরাং কোডটি চালিয়ে যেতে হবে এবং এটি দেখানোর চেষ্টা করবে, যদিও আমি অন্য কোনও ক্রিয়াকলাপে ছিলাম। তবে এটি ক্র্যাশ বন্ধ করে দিয়েছিল এবং আমি সহজেই নতুন ক্রিয়াকলাপে চলে গেলাম!
আজুরস্পট

1
অনেক অনুরূপ প্রশ্ন আছে, কিন্তু তাদের কোনটিতেই এটি প্রস্তাব করা হয়নি। ব্যক্তিগতভাবে এটিই আমার দৃশ্যের একমাত্র সঠিক সমাধান ছিল।
ফিলোবোটো

এর জন্য কোটলিন সংস্করণ কী? ফিনিশিং () কি যথেষ্ট হবে?
অলোক রাজাসুকুমারন

12

আমি একই সমস্যার মুখোমুখি হয়েছি এবং উপরে ডিস্কেভের প্রস্তাবিত কোডটি নিম্নরূপ পরিবর্তন সহ ব্যবহার করেছি :

if (!MainActivity.this.isFinishing()){
    alertDialog.show();
}

আমি পরিবর্তন করেছি কারণ (ক্রিয়াকলাপ) প্রসঙ্গটি আমার মামলার জন্য মূল কার্যকলাপ ছিল th এটি ছিল। এছাড়াও আপনি ব্যবহারকারী প্রোফাইল লিঙ্ক সম্পর্কে সঠিক, কিন্তু আমি ভেবেছিলাম যে আপনি এটি উপরে খুঁজে পেতে পারেন।
হামজা পোলাট

4

থ্রেডের কারণে যদি ডায়লগটি এই সমস্যাটিকে ঘুরছে তবে আপনার এটি ইউআই থ্রেডের মতো চালানো উচিত: -

runOnUiThread(new Runnable() {
            @Override
            public void run() {
                dialog.show();

            }
        });

2

এই ত্রুটিটি তখন ঘটে যখন আপনি কোনও প্রসঙ্গের জন্য ডায়ালগটি দেখানোর সময় উপস্থিত থাকেন না।

কল করার আগে .show()পরীক্ষা করুন যে ক্রিয়াকলাপ / প্রসঙ্গটি শেষ হচ্ছে না

if (!(context instanceof Activity && ((Activity) context).isFinishing())) {
    alert.show();
}

1

countDownTimerআমার অ্যাপটিতে থাকা অবস্থায় আমি এই ত্রুটির মুখোমুখি হয়েছি । এটিতে আমার অ্যাপ্লিকেশনটিতে গেমওভারকে কল করার একটি পদ্ধতি ছিল

public void onFinish() {
     GameOver();
}

তবে আসলে ব্যবহারকারীর ভুল ক্লিকের কারণে সময় শেষ হওয়ার আগেই খেলাটি শেষ হয়ে যেতে পারে (এটি একটি ক্লিকের খেলা ছিল)। সুতরাং আমি যখন 20 সেকেন্ডের পরে গেম ওভার ডায়ালগটির দিকে তাকিয়ে ছিলাম, সময় শেষ হয়ে যাওয়ার পরে আমি countDownTimerতাই বাতিল করতে ভুলে গিয়েছিলাম , ডায়ালগটি আবার উপস্থিত হয়েছিল। অথবা কোনও কারণে উপরের ত্রুটির সাথে ক্র্যাশ হয়েছে।


1

এটি সমাধান খুব সহজ। ডায়ালগটি প্রদর্শনের আগে ক্রিয়াকলাপটি শেষ পর্যায়ে চলছে কিনা তা পরীক্ষা করুন:

  private Handler myHandler = new Handler() {
  @Override
  public void handleMessage(Message msg) {
    switch (msg.what) {
      case DISPLAY_DLG:
        if (!isFinishing()) {
        showDialog(MY_DIALOG);
        }
      break;
    }
  }
};

আরও এখানে দেখুন


1

আমার ক্ষেত্রে, সমস্যাটি Contextক্লাসে প্রসারিত দুর্বল রেফারেন্স হিসাবে রাখা হয়েছিল Handler। তারপরে আমি যাচ্ছিলাম Messenger, যা হ্যান্ডলারের মোড়ানো, একটি মাধ্যমে Intentএকটি Service। ক্রিয়াকলাপটি onResume()পদ্ধতিতে স্ক্রিনে উপস্থিত হওয়ার সময় আমি প্রতিটি সময় এটি করছিলাম ।

আপনি যেমন বুঝতে পেরেছেন, মেসেঞ্জারকে এর ক্ষেত্রগুলি (প্রসঙ্গ সহ) একসাথে সিরিয়ালযুক্ত করা হয়েছিল, কারণ এটি ব্যবহার করে অবজেক্টগুলি পাস করার একমাত্র উপায় Intent সিরিয়াল করার জন্য - । সেই মুহুর্তে যখন মেসেঞ্জার পরিষেবাতে চলে গিয়েছিল, তত্ক্ষণাত্ ক্রিয়াকলাপটি অন্য কোনও অবস্থায় রয়েছে বলে কথোপকথন প্রদর্শনের জন্য প্রস্তুত ছিল না (অনারিউম বলা হচ্ছে), এটি ক্রিয়াকলাপটি ইতিমধ্যে স্ক্রিনে থাকা থেকে একেবারেই আলাদা। সুতরাং ম্যাসেঞ্জারকে যখন ডিসস্রাইজ করা হয়েছিল, তখন প্রসঙ্গটি পুনরায় শুরু হওয়া অবস্থায় ছিল, যখন ক্রিয়াকলাপটি ইতিমধ্যে পর্দায় ছিল। তদুপরি, ডিসরিয়ালাইজেশন নতুন অবজেক্টের জন্য মেমরি বরাদ্দ করে, এটি আসলটি থেকে সম্পূর্ণ পৃথক।

সমাধানটি কেবলমাত্র যখনই আপনার প্রয়োজন হবে সেবার সাথে আবদ্ধ হওয়া এবং 'সেট ম্যাসেঞ্জার (মেসেঞ্জার মেসেঞ্জার) এর মতো পদ্ধতি রয়েছে এমন একটি বাইন্ডার ফিরিয়ে দেওয়া এবং যখন আপনি পরিষেবাতে আবদ্ধ হন, তখন এটি কল করুন।


1

আমি WeakReference<Activity>প্রসঙ্গ হিসাবে ব্যবহার করে এই সমস্যাটি সমাধান করি । ক্র্যাশ আর দেখা যায় নি। এখানে কোটলিনে একটি নমুনা কোড রয়েছে:

ডায়ালগ ম্যানেজার শ্রেণি:

class DialogManager {

        fun showAlertDialog(weakActivity: WeakReference<Activity>) {
            val wActivity = weakActivity.get()
            wActivity?.let {
                val builder = AlertDialog.Builder(wActivity, R.style.MyDialogTheme)
                val inflater = wActivity.layoutInflater
                val dialogView = inflater.inflate(R.layout.alert_dialog_info, null)
                builder.setView(dialogView)

                // Set your dialog properties here. E.g. builder.setTitle("MyTitle")

                builder.create().show()
            }
         }

}

এবং আপনি এই জাতীয় কথোপকথনটি প্রদর্শন করুন:

 val dialogManager = DialogManager()
 dialogManager.showAlertDialog(WeakReference<Activity>(this@MainActivity))

আপনি যদি চান সুপার-ডুপার ক্র্যাশ থেকে সুরক্ষিত। পরিবর্তে builder.create().show()ব্যবহার:

val dialog = builder.create()
safeShow(weakActivity, dialog)

এই safeShowপদ্ধতি:

private fun safeShow(weakActivity: WeakReference<Activity>, dialog: AlertDialog?) {
        val wActivity = weakActivity.get()
        if (null != dialog && null != wActivity) {
            // Api >=17
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                if (!dialog.isShowing && !(wActivity).isFinishing && !wActivity.isDestroyed) {
                    try {
                        dialog.show()
                    } catch (e: Exception) {
                        //Log exception
                    }
                }
            } else {

                // Api < 17. Unfortunately cannot check for isDestroyed()
                if (!dialog.isShowing && !(wActivity).isFinishing) {
                    try {
                        dialog.show()
                    } catch (e: Exception) {
                        //Log exception
                    }
                }
            }
        }
    }

এটি একটি অনুরূপ পদ্ধতি যা আপনি ডায়ালগটি নিরাপদে বরখাস্ত করার জন্য ব্যবহার করতে পারেন:

private fun safeDismissAlertDialog(weakActivity: WeakReference<Activity>, dialog: AlertDialog?) {
        val wActivity = weakActivity.get()
        if (null != dialog && null != wActivity) {
            // Api >=17
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                if (dialog.isShowing && !wActivity.isFinishing && !wActivity.isDestroyed) {
                    try {
                        dialog.dismiss()
                    } catch (e: Exception) {
                        //Log exception
                    }
                }
            } else {

                // Api < 17. Unfortunately cannot check for isDestroyed()
                if (!dialog.isShowing && !(wActivity).isFinishing) {
                    try {
                        dialog.dismiss()
                    } catch (e: Exception) {
                        //Log exception
                    }
                }
            }
        }
    }

0

কীভাবে আপনি যে ডায়ালগটি কল করতে চান তার একটি নতুন ইনস্ট্যান্স তৈরি করে? আমি আসলে ঠিক একই সমস্যাটির মুখোমুখি হয়েছি এবং আমি এটিই করি। বরং এর চেয়ে:

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

এ কেমন?

 YourDialog mDialog = new YourDialog();
 mDialog1.show(((AppCompatActivity) mContext).getSupportFragmentManager(), "OrderbookDialog");
                        }

সুতরাং ডায়লগটি দেখানো নিরাপদ কিনা তা যাচাই করা না করে বরং আমি মনে করি ডায়ালগটি দেখানোর জন্য যদি আমরা একটি নতুন উদাহরণ তৈরি করি তবে এটি অনেক বেশি নিরাপদ ।

আমার মত, আমার ক্ষেত্রে আমি একটি দৃষ্টান্ত তৈরি করার চেষ্টা করেছি (একটি ফ্রেগমেন্ট অনক্রিয়েট থেকে ) এবং অ্যাডাপ্টারলিস্টের অন্য সামগ্রীতে সেই কথোপকথনের উদাহরণটি কল করেছি এবং এর ফলে "আপনার কার্যকলাপ চলছে" - ত্রুটি হবে । আমি ভেবেছিলাম এটি কারণ আমি কেবলমাত্র একটি উদাহরণ তৈরি করেছি (অনক্রিয়েট থেকে) এবং তারপরে এটি ধ্বংস হয়ে যায়, তাই যখন আমি এটি অন্য অ্যাডাপ্টারলিস্ট থেকে কল করার চেষ্টা করতাম তখন আমি ডায়ালগটিকে পুরানো উদাহরণ থেকে কল করি।

আমার সমাধানটি মেমোরি বান্ধব কিনা তা আমি নিশ্চিত নই, কারণ আমি এটির প্রোফাইল দেওয়ার চেষ্টা করি নি, তবে এটি কার্যকর হয় (আপনি অবশ্যই খুব বেশি উদাহরণ তৈরি না করলে এটি নিরাপদ)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.