registerReceiver from IntentService doesn't hi

2019-08-02 19:28发布

I've created an IntentService for downloading a file using Android's DownloadManager. Following is my Class:

public class DownloadService extends IntentService {

   public DownloadService() {
        super("name");
    }

    BroadcastReceiver onComplete = new BroadcastReceiver() {
        public void onReceive(Context ctxt, Intent intent) {
            function();
         }
       };

    @Override
    protected void onHandleIntent(Intent intent) {
        registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
        Utility.download(someURL);

       }

    }

I've this entry in manifest:

        <service
            android:name=".services.DownloadService"
            android:enabled="true" >
        </service>

The code inside BroadcastReceiver(function()) is never executing even if the file is downloaded. I also tried doing the same thing in Service instead of IntentService, it worked. How can I make BroadcastReceiver work inside IntentService?

1条回答
狗以群分
2楼-- · 2019-08-02 19:59

Avoid calling registerReceiver method using IntentService's context.

Once your IntentService#onHandleIntent method returns, the Service#stopSelf(int) method will be called. All the not-yet-unregistered receivers will be considered as leaked. The framework even warns you about that:

E/ActivityThread﹕ Service com.your.packagename.YourIntentService has leaked IntentReceiver com.your.packagename.YourReceiver@41f4cd08 that was originally registered here. Are you missing a call to unregisterReceiver()?
    android.app.IntentReceiverLeaked: Service com.your.packagename.YourIntentService has leaked IntentReceiver com.your.packagename.YourReceiver@41f4cd08 that was originally registered here. Are you missing a call to unregisterReceiver()?
    at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:796)
    at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:597)
    at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1438)
    at android.app.ContextImpl.registerReceiver(ContextImpl.java:1418)
    at android.app.ContextImpl.registerReceiver(ContextImpl.java:1412)
    at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:467)
    at com.your.packagename.YourIntentService.onHandleIntent(YourIntentService.java:79)
    at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:136)
    at android.os.HandlerThread.run(HandlerThread.java:61)

And of course, none of your leaked broadcast receivers will receive notifications afterwards.

If you still want to register the broadcast receiver within IntentService#onHandleIntent method, use (for example) Application's context for that.

getApplication().registerReceiver(receiverInstance,  
        new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));

Note however, that you'll have to add logic that unregisters each such receiver instance once you finish with it.

查看更多
登录 后发表回答