【问题标题】:BroadcastReceiver with ResultReceiver and lifetime具有 ResultReceiver 和生命周期的 BroadcastReceiver
【发布时间】:2014-05-19 11:54:51
【问题描述】:

我询问了使用带有 ResultReceiver 的 BroadcastReceiver 的方式。

我知道如果“A BroadcastReceiver 没有在 10 秒内完成执行。”,就会出现 ANR。

我有一个响应 Intent 的应用程序,在 Manifest 中声明。 它是一个 BroadcastReceiver 启动一个服务,因为它需要进行一些网络操作:

public class MyReceiver extends BroadcastReceiver {

    private Context context = null;
    private MyResultReceiver myResultReceiver = null;

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

        this.context = context;
        myResultReceiver = new MyResultReceiver(new Handler());

        Intent i = new Intent();
        i.setClass(context, MyService.class);
        i.putExtra(Constants.EXTRA_RESULT_RECEIVER, myResultReceiver);
        context.startService(i);
    }

    public class MyResultReceiver extends ResultReceiver {

        public MyResultReceiver(Handler handler) {
            super(handler);
        }

        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            if (resultCode == 42) {
                // Something
            } else {
                // Something else
            }
        }
    }
}

我的服务如下所示:

public class MyService extends Service {

    private Context context = null;
    private ResultReceiver resultReceiver = null;

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        this.context = this;
        resultReceiver = intent.getParcelableExtra(Constants.EXTRA_RESULT_RECEIVER);
        MyTask myTask = new MyTask();
        myTask.execute();
        return super.onStartCommand(intent, flags, startId);
    }

    public class MyTask extends AsyncTask<Void, Void, Boolean> {

        @Override
        protected Boolean doInBackground(Void... params) {
            // Network operation
            return status;
        }

        @Override
        protected void onPostExecute(final Boolean status) {
            Bundle bundle = new Bundle();
            if (status == true) {
                if (resultReceiver != null) {
                    resultReceiver.send(42, null);
                }
            } else {
                if (resultReceiver != null) {
                    resultReceiver.send(-1, null);
                }
            }
        }
    }
}

我的问题是,如果网络操作超过 10 秒,我确定 resultReceiver 仍然存在并且会做它必须做的事情吗?

【问题讨论】:

    标签: android android-intent broadcastreceiver android-service


    【解决方案1】:

    这是来自 SDK 的 relevant documentation

    如果这个 BroadcastReceiver 是通过标签启动的,那么 从该函数返回后,该对象不再存在。这 意味着您不应该执行任何返回结果的操作 你异步 - 特别是与服务交互, 你应该使用 startService(Intent) 而不是 bindService(Intent, 服务连接,整数)。如果您希望与以下服务进行交互 已经在运行,你可以使用 peekService(Context, Intent)。

    registerReceiver(BroadcastReceiver, IntentFilter) 和应用程序清单不保证是 独家的。它们是操作系统有关如何查找的提示 合适的收件人。发件人可以强制发送到 特定收件人,绕过过滤器解析。为此原因, onReceive() 实现应仅响应已知操作, 忽略他们可能收到的任何意外 Intent。

    底线:

    1. 如果您启动服务,请使用startService(Intent)
    2. 不要在 onReceive 上运行长时间运行的应用程序。
    3. AsyncTasks 可能会被破坏,最好的办法是使用服务。如果您在 Service 中使用 AsyncTask,应该没问题。

    【讨论】:

    • WRT 你的“底线” - 1. OP IS 使用startService(...)。 2. OP 知道这一点,因此提出了这个问题。 3. OP IS 使用Service。诚然,在 Service 中使用 AsyncTask 是没有意义的(请记住,AsyncTask 旨在与 UI 交互),但即便如此,AsyncTaskService 中被破坏的可能性也要小得多。在Activity.
    • 正如@Squonk 所说,这个答案对我没有帮助。但是感谢您的尝试。
    猜你喜欢
    • 2011-09-12
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-10
    • 1970-01-01
    • 2019-08-05
    相关资源
    最近更新 更多