【问题标题】:Why my BroadcastReceiver stop receiving after a while为什么我的 BroadcastReceiver 在一段时间后停止接收
【发布时间】:2016-05-03 22:02:19
【问题描述】:

我有一个IntentService,它的工作很长,大约需要 15 分钟才能完成。这是从我的服务器获取新数据的同步过程。

此服务启动时,我也启动一个活动,以显示进度。

此活动创建一个BroadcastReceiver,它拦截从服务发送的有关进程进度的消息。

如果我让应用程序继续工作,一段时间后 SO 会关闭屏幕。

当我再次打开屏幕时,大约 15 分钟后,服务已经完成,但进度似乎已过时。 BroadcastReceiver 已停止工作,而我的 END OF SYNCHRONIZATION 消息尚未被 Activity 接收。

问题在于,在此消息中,我再次启动主要活动以让用户再次使用该应用程序。

我该如何解决这个问题?

【问题讨论】:

  • 发布一些代码...我猜您的活动没有收到消息,因为您的接收器未注册 onPause 或 onDestroy,但很难说,因为没有代码。我建议使用 serviceBinding 和 Messengers 而不是收听广播接收器,并在您的活动绑定时发送状态消息,以获取最新状态......但同样,代码会有所帮助。
  • @AdamW 广播在 onStart 和 onStop 方法中注册和注销。

标签: android android-service android-broadcast android-broadcastreceiver


【解决方案1】:

广播接收器不是用来做长时间工作的。

广播接收器的生命周期大约持续 10-15 秒。

广播接收器的推荐或典型用途是

  • 启动服务
  • 举杯敬酒
  • 开始一个活动

在您的情况下,您应该从广播接收器启动服务并完成该服务中的所有工作。

【讨论】:

    【解决方案2】:

    我用这个http://developer.android.com/intl/pt-br/guide/components/services.html#Foreground 解决了。

    我的服务

    public class MyService extends Service {
    
        public interface MyCallback {
            void onProgress(int progress);
        }
    
        public class MyBinder {
            public MyService getService() {
                return MyService.this;
            }
        }
    
        public IBinder onBind(Intent intent) {
            return new MyBinder();
        }
    
        public void make(MyCallback callback) {
    
            Notification n = new Notification.Builder(this)
                .setContentTitle("Processing")
                .getNotification();
    
            startForeground(666 /*some ID*/, n);
            try {
                callback.onProgress(0);
                // do the hard sutff and report progress
                callback.onProgress(100); // report 100%
            } finally {
                stopForeground(true);
            }
        }
    }
    

    我的活动

    public MyActivity extends Activity implements ServiceConnection, MyService.MyCallback {
    
        @Override
        protected onStart() {
            super.onStart();
            // 1 - bind service to this activity
            Intent i = new Intent(this, MyService.class);
            this.bindService(i, this, BIND_AUTO_CREATE);
        }
    
        @Override
        public void onServiceConnected(ComponentName componentName, final IBinder iBinder) {
            // 2 - when the service was binded, starts the process asynchronous
            new AsyncTask<Void, Void, Void>() {
                @Override
                protected Void doInBackground(Void... voids) {
                    ((MyService.MyBinder) iBinder).getService().make(MyActivity.this);
                    return null;
                }
            }.execute();
        }
    
        @Override
        public void onProgress(int progress) {
            // 3 - when to callback is fired, update the UI progress bar
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // call ProgressBar.setProgress(progress);
                }
            });
        }
    
    }
    

    【讨论】:

      最近更新 更多