রিসিভার ব্যতিক্রম ত্রুটি নিবন্ধিত না?


112

আমার বিকাশকারী কনসোলে লোকেরা এমন ত্রুটির প্রতিবেদন করে যা আমি থাকা কোনও ফোনে পুনরুত্পাদন করতে পারি না। একজন ব্যক্তি বার্তা রেখে বলেছিল যে তারা যখন আমার ব্যাটারি পরিষেবার সেটিংস স্ক্রিনটি খোলার চেষ্টা করে তখন তা পেয়ে যায়। আপনি ত্রুটি থেকে দেখতে পাচ্ছেন যে এটি রিসিভারটি নিবন্ধীকৃত নয়।

java.lang.RuntimeException: Unable to stop service .BatteryService@4616d688:  java.lang.IllegalArgumentException: Receiver not registered: com.app.notifyme.BatteryService$BatteryNotifyReceiver@4616d9d0
at android.app.ActivityThread.handleStopService(ActivityThread.java:3164)
at android.app.ActivityThread.access$3900(ActivityThread.java:129)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2173)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:143)
at android.app.ActivityThread.main(ActivityThread.java:4701)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: Receiver not registered:com..BatteryService$BatteryNotifyReceiver@4616d9d0
at android.app.ActivityThread$PackageInfo.forgetReceiverDispatcher(ActivityThread.java:805)
at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:859)
at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:331)
at com.app.notifyme.BatteryService.onDestroy(BatteryService.java:128)
at android.app.ActivityThread.handleStopService(ActivityThread.java:3150)

আমি রেজিস্ট্রেশন আমার অনক্রিট হয়

@Override
public void onCreate(){
    super.onCreate();
    SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
    IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
    filter.addAction(Intent.ACTION_POWER_CONNECTED);
    filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
    registerReceiver(batteryNotifyReceiver,filter);
    pref.registerOnSharedPreferenceChangeListener(this);
}

অনডেট্রয়ে নিবন্ধভুক্ত করুন এবং অগ্রাধিকার শ্রোতার সাথেও

    @Override
public void onDestroy(){
    super.onDestroy();
    unregisterReceiver(batteryNotifyReceiver);

}

এবং এই পরিষেবাতে আমার রিসিভার

private final class BatteryNotifyReceiver extends BroadcastReceiver {

    boolean connected;
    @Override
    public void onReceive(Context context, Intent intent) {

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); 
        SharedPreferences.Editor edit = prefs.edit();

            updatePreferences(prefs);

        level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);



        if(intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)){
            connected = true;
        }else if(intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED)){
            connected = false;
        }else if(intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)){

                if(level < lastLevel){
                    if(level > 40){
                        edit.putBoolean("first", false).commit();
                        edit.putBoolean("second", false).commit();
                        edit.putBoolean("third", false).commit();
                       edit.putBoolean("fourth",false).commit();                            
                        edit.putBoolean("fifth", false).commit();
                    }
                    if(level == 40){
                        if(!first){
                        notification(context,battColor,battBlink,battVib,battSound);

                        edit.putBoolean("first", true).commit();
                        }
                    }else if(level == 30){
                        if(!second){
                        notification(context,battColor,battBlink,battVib,battSound);

                        edit.putBoolean("second", true).commit();
                        }
                    }else if(level == 20){
                        if(!third){
                        notification(context,battColor,battBlink,battVib,battSound);

                        edit.putBoolean("third", true).commit();
                        }
                    }else if(level == 15){
                        if(!fourth){
                        notification(context,battColor,battBlink,battVib,battSound);

                        edit.putBoolean("fourth", true).commit();
                        }
                    }else if(level == 5){
                        if(!fifth){
                        notification(context,battColor,battBlink,battVib,battSound);

                        edit.putBoolean("fifth", true).commit();
                        }
                    }
                lastLevel = temp;
            }
        }           

        Intent i = new Intent(context,BatteryNotifyReceiver.class);
        context.startService(i);
    }       
}

কোন ধারণা কেন তারা সেই ত্রুটি পাবে?

উত্তর:


207

আপনার সমস্যার মূল এখানে অবস্থিত:

 unregisterReceiver(batteryNotifyReceiver);

যদি রিসিভারটি ইতিমধ্যে নিবন্ধভুক্ত ছিল (সম্ভবত যে কোডটিতে আপনি এই পোস্টে অন্তর্ভুক্ত করেননি) বা নিবন্ধভুক্ত না হয়ে থাকেন, তবে unregisterReceiverনিক্ষেপ করতে কল করুন IllegalArgumentException। আপনার ক্ষেত্রে আপনার এই ব্যতিক্রমটির জন্য বিশেষ চেষ্টা / ধরা এবং এটিকে উপেক্ষা করা দরকার (ধরে unregisterReceiverনিলে আপনি একই গ্রহণকারীর সাথে কল করার সময় আপনি নিয়ন্ত্রণ করতে পারবেন না বা করতে চান না )।


31
অ্যান্ড্রয়েড প্ল্যাটফর্মের পক্ষে এটি করা কি সম্ভব? আমার উপরের মত একই কোড ছিল, তবে পরিষেবাটি নিবন্ধভুক্ত করতে হবে এমন কোনও অন্য কোড ছাড়াই এবং আমি একই ব্যতিক্রম পাই।
বৈদ্যুতিন

2
@ ইলেক্ট্রিকহেডে আমার একই সমস্যা আছে, আমি দেখতে পাচ্ছি না যে রিসিভারটি অনড্রেস্টের আগে নিবন্ধিত হবে () যদি না অ্যান্ড্রয়েড কোথাও আমার জন্য কাজ করে থাকে ....
ব্যবহারকারী 1088166

@ ব্যবহারকারী 1088166, আপনার ক্রিয়াকলাপের জন্য অনটপ () পদ্ধতিটি ওভাররাইড করার চেষ্টা করুন। সেখানে একটি চেষ্টা করে ক্যাচ যুক্ত করুন (অবৈধ অর্গগমেন্ট এক্সপশন ই) এবং উদ্দেশ্যমূলকভাবে আপনার সম্প্রচারটি নিবন্ধভুক্ত করুন - দেখুন এটি সাহায্য করে কিনা (দেখুন এটি কেবল 3 বছরের পুরানো মন্তব্য :))
ন্যাকটাস

আমার ক্ষেত্রে অপরাধী অলস সূচনা হয়েছিল - আমি নিবন্ধকরণ এড়িয়ে গেছি কারণ অবজেক্টটি আরম্ভ হয়নি, তাই এটি পরে আরম্ভ করা হয়েছিল এবং আমি প্রাপক নিবন্ধকরণ ভুলে গিয়েছিলাম।
বরিস ত্রেখভভ

@ ইলেক্ট্রিকহেড না, এটি আপনার জন্য এটি করে না, আপনাকে কেবল সঠিক পদ্ধতিটি চয়ন করতে হবে: LocalBroadcastManager.getInstance(context).unregisterReceiver()বাcontext.unregisterReceiver()
ব্যবহারকারী 924

25

সাবধান থাকুন, যখন আপনি রেজিস্ট্রেশন করবেন

LocalBroadcastManager.getInstance(this).registerReceiver()

আপনি দ্বারা নিবন্ধন করতে পারবেন না

 unregisterReceiver()

আপনার অবশ্যই ব্যবহার করা উচিত

LocalBroadcastManager.getInstance(this).unregisterReceiver()

বা অ্যাপ্লিকেশন ক্রাশ হবে, অনুসরণ হিসাবে লগ করুন:

09-30 14: 00: 55.458 19064-19064 / com.jialan.guangdian.view ই / অ্যান্ড্রয়েডআরআনটাইম: চূড়ান্ত ব্যতিক্রম: প্রধান প্রক্রিয়া: com.jialan.guangdian.view, পিআইডি: 19064 java.lang.আরুনটাইম এক্সসেপশন: পরিষেবা বন্ধ করতে অক্ষম com.google.android.exoplayer.demo.player.PlayService@141ba331: java.lang.IllegalArgumentException: প্রাপক নিবন্ধিত নয়: com.google.android.exoplayer.demo.player.PlayService$PlayStatusReceiver@19538584 এ androidTapp.c. এ। android.app.ActivityThread.access $ 2200 এ (অ্যাক্টিভিটিথ্রেড.জভা: হ্যান্ডেলটপসপরিভিশন (অ্যাক্টিভিটিথ্রেড.জবা ২৯৪৪১))148) এ android.app.ActivityThread $ H.handleMessage (ActivityThread.java 1395) at android.os.Handler.dispatchMessage (Handler.java:102) at android.os.Looper.loop (Looper.javaament35) at android.app.ActivityThread.main (ActivityThread.java:5310) at java.lang.reflect.Method.invoke (নেটিভ পদ্ধতি) at java.lang.reflect.Method.invoke (মেথড.জভা:372) এ com.android.intern.os.ZygoteInit $ মেথডএন্ডআরএজস ক্যালারআরুন (জাইগোটইনিট.জভা: 901) এ com.android.intern.os.ZygoteInit.main (জাইগোটইনিট.জভা:696) এর কারণ: java.lang.xlementXial : রিসিভার নিবন্ধীকৃত নয়: com.google.android.exoplayer.demo.player.PlayService$PlayStatusReceiver@19538584 এ android.app.LoadeApk.forgetReceiverDispatcher (LoadedApk.java:769) এ android.app.ConteisterIp.ConteisterIliampi.pontextIliampi.pontextIliampi.pontextrepliempi.png1794) এন্ড্রয়েড.অ্যাপ.অ্যাক্টিভিটিশ্রেড.সেপশনসেডস্রোপসিটারসেড্রাইসট্রপস্রপসে (PlayService.java:542) at com.google.android.exoplayer.demo.player.PlayService.onDestroy (PlayService.java:542) এ android.content.ContextWrapper.unregisterReceiver (ContextWrapper.java:51010) এ .java: 2924) এ android.app.ActivityThread.access $ 2200 (ActivityThread.java:148) এ android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1395) android.os.Handler.dispatchMessage (Handler.java:1022) এ android.os.Looper.loop (Looper.javaimar35) at android.app.ActivityThread.main (ActivityThread.java:5310) জাভাতে। lang.reflect.Method.invoke (নেটিভ মেথড) at java.lang.reflect.Method.invoke (মেথড.জভা ৩72২২) এ com.android.intern.os.ZygoteInit $ মেথডএন্ডআর্গসকলারআরুন (জাইগোটআইনিট.জভা:901) এ com.android.intern.os.ZygoteInit.main (জাইগোটইনিট.জভা:696) 


এটি এই সমস্যার আসল উত্তর! আপনি যদি কোনও বিশ্বব্যাপী বা স্থানীয় রিসিভারটি নিবন্ধভুক্ত করেন তবে কেবল ভুলে যাবেন না
user924

23

নিবন্ধভুক্ত রিসিভারের জন্য এই কোডটি সর্বত্র ব্যবহার করুন:

if (batteryNotifyReceiver != null) {
    unregisterReceiver(batteryNotifyReceiver);
    batteryNotifyReceiver = null;
}

6
এখনও আমার সাথে ঘটে। আরও ভাল ব্যবহার চেষ্টা করুন।
প্যালিনড্রম

2
ক্যাচ স্টেটমেন্টটি আরও ভাল
রাওল্যান্ড মতেতেজী

16

অন্যান্য উত্তরে উল্লিখিত হিসাবে, ব্যতিক্রম নিক্ষেপ করা হচ্ছে কারণ প্রতিটি কলটিতে registerReceiverএকটি কল করার সাথে মিল নেই unregisterReceiver। কেন না?

একটি Activityসবসময় একটি মানানসই নেই onDestroyযে আহ্বান onCreateকল। যদি সিস্টেমটি মেমরির বাইরে চলে যায় তবে আপনার অ্যাপটিকে কল না করেই উচ্ছেদ করা হবে onDestroy

registerReceiverকল দেওয়ার সঠিক জায়গাটি onResumeকলটিতে এবং unregisterReceiverভিতরে রয়েছে onPause। এই জোড়া কল সবসময় মেলে। আরও তথ্যের জন্য ক্রিয়াকলাপ জীবনচক্র ডায়াগ্রাম দেখুন। http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle

আপনার কোড এতে পরিবর্তিত হবে:

SharedPreferences mPref
IntentFilter mFilter;

@Override
public void onCreate(){
    super.onCreate();
    mPref = PreferenceManager.getDefaultSharedPreferences(this);
    mFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
    filter.addAction(Intent.ACTION_POWER_CONNECTED);
    filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
 }

@Override
public void onResume() {
    registerReceiver(batteryNotifyReceiver,mFilter);
    mPref.registerOnSharedPreferenceChangeListener(this);
}

@Override
public void onPause(){
     unregisterReceiver(batteryNotifyReceiver, mFilter);
     mPref.unregisterOnSharedPreferenceChangeListener(this);
}

তবে এটি আরও অনেকবার নিবন্ধন এবং নিবন্ধন করার ওভারহেডের কারণ হতে পারে। আমি ওভারহেডের পরিমাণ সম্পর্কে নিশ্চিত নই তবে নিশ্চিতভাবে কিছু থাকবে।
আমান দীপ গৌতম

2
আপনি কি সত্যিই জায়গায় অবৈধ হ্যান্ডলার ছুঁড়ে ফেলে ব্যতিক্রম করার পরামর্শ দিচ্ছেন কারণ এটি সরিয়ে ফেলতে কিছু সিপিইউ চক্র লাগবে?
কার্মুডজোনলিবিম্বলি

11

সম্পাদনা: ইনাজারুক এবং ইলেকট্রিকহেডের জন্য এটিই উত্তর ... আমি তাদের সাথে একটি অনুরূপ ইস্যু নিয়েছিলাম এবং নিম্নলিখিতগুলি খুঁজে পেয়েছি ...

এই সমস্যার জন্য এখানে দীর্ঘস্থায়ী বাগ রয়েছে: http://code.google.com/p/android/issues/detail?id=6191

দেখে মনে হচ্ছে এটি অ্যান্ড্রয়েড ২.১-এর আশেপাশে শুরু হয়েছিল এবং তখন থেকে অ্যানড্রয়েড ২.x রিলিজের মধ্যে উপস্থিত রয়েছে। যদিও এখনও অ্যান্ড্রয়েড 3.x বা 4.x এ সমস্যা আছে কিনা তা আমি নিশ্চিত নই।

যাইহোক, এই স্ট্যাকওভারফ্লো পোস্টটি ব্যাখ্যা করে যে কীভাবে সমস্যাটিকে সঠিকভাবে সমাধান করতে হবে (এটি ইউআরএল দ্বারা প্রাসঙ্গিক বলে মনে হচ্ছে না তবে আমি প্রতিশ্রুতি দিচ্ছি)

কীবোর্ড-স্লাইড কেন আমার অ্যাপটিকে ক্রাশ করে?


8

সাময়িকভাবে সমস্যা সমাধানের জন্য আমি একটি চেষ্টা - ক্যাচ ব্লক ব্যবহার করেছি।

// Unregister Observer - Stop monitoring the underlying data source.
        if (mDataSetChangeObserver != null) {
            // Sometimes the Fragment onDestroy() unregisters the observer before calling below code
            // See <a>http://stackoverflow.com/questions/6165070/receiver-not-registered-exception-error</a>
            try  {
                getContext().unregisterReceiver(mDataSetChangeObserver);
                mDataSetChangeObserver = null;
            }
            catch (IllegalArgumentException e) {
                // Check wether we are in debug mode
                if (BuildConfig.IS_DEBUG_MODE) {
                    e.printStackTrace();
                }
            }
        }

3

রিসিভারটি নাল হিসাবে ঘোষণা করুন এবং তারপরে ক্রিয়াকলাপের যথাক্রমে onResume () এবং onPause () এ নিবন্ধভুক্ত করুন এবং নিবন্ধভুক্ত পদ্ধতিগুলি রাখুন।

@Override
protected void onResume() {
    super.onResume();
    if (receiver == null) {
        filter = new IntentFilter(ResponseReceiver.ACTION_RESP);
        filter.addCategory(Intent.CATEGORY_DEFAULT);
        receiver = new ResponseReceiver();
        registerReceiver(receiver, filter);
    }
}      

@Override
protected void onPause() {
    super.onPause();
    if (receiver != null) {
        unregisterReceiver(receiver);
        receiver = null;
    }
}

0

যখন বিআই নিবন্ধভুক্ত ইউআই উপাদান নষ্ট হয়ে যায়, তেমনি বিআরও হয়। সুতরাং কোডটি নিবন্ধভুক্ত করার সময়, বিআর ইতিমধ্যে ধ্বংস হয়ে যেতে পারে।


0

যে কেউ এই সমস্যাটি নিয়ে আসবে এবং তারা প্রস্তাবিত সমস্ত কিছু চেষ্টা করেছিল এবং এখনও কিছুই কার্যকর হয় না, এইভাবে আমি আমার সমস্যাটি বাছাই করেছিলাম, না করে LocalBroadcastManager.getInstance(this).registerReceiver(...) আমি প্রথমে লোকালবার্তা সম্প্রচার ম্যানেজার টাইপের একটি স্থানীয় ভেরিয়েবল তৈরি করেছি,

private LocalBroadcastManager lbman;

এবং এই পরিবর্তনশীলটি ব্রডকাস্ট্রেসিভারে নিবন্ধকরণ এবং নিবন্ধন সম্পাদন করতে ব্যবহার করে

lbman.registerReceiver(bReceiver);

এবং

lbman.unregisterReceiver(bReceiver);

0

ধরে নেওয়া যাক আপনার broadcastReceiverএইরকম সংজ্ঞা দেওয়া হয়েছে:

private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

        // your code

    }
};

আপনি যদি LocalBroadcastকোনও ক্রিয়াকলাপ ব্যবহার করে থাকেন তবে আপনি এভাবেই নিবন্ধন করবেন:

LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);

আপনি যদি LocalBroadcastকোনও খণ্ডে ব্যবহার করে থাকেন তবে আপনি এভাবেই নিবন্ধন করবেন:

LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(broadcastReceiver);

আপনি যদি কোনও ক্রিয়াকলাপে সাধারণ সম্প্রচার ব্যবহার করে থাকেন তবে আপনি এভাবে নিবন্ধন করবেন:

unregisterReceiver(broadcastReceiver);

আপনি যদি কোনও খণ্ডে সাধারণ সম্প্রচার ব্যবহার করে থাকেন তবে আপনি এভাবেই নিবন্ধন করবেন:

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