具有 ResultReceiver 和生命周期的 BroadcastReceiver

Posted

技术标签:

【中文标题】具有 ResultReceiver 和生命周期的 BroadcastReceiver【英文标题】:BroadcastReceiver with ResultReceiver and lifetime 【发布时间】: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 仍然存在并且会做它必须做的事情吗?

【问题讨论】:

【参考方案1】:

这是来自 SDK 的 relevant documentation:

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

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

底线:

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

【讨论】:

WRT 你的“底线” - 1. OP IS 使用startService(...)。 2. OP 知道这一点,因此提出了这个问题。 3. OP IS 使用Service。诚然,在 Service 中使用 AsyncTask 是没有意义的(请记住,AsyncTask 旨在与 UI 交互),但即便如此,AsyncTaskService 中被破坏的可能性也要小得多。在Activity. 正如@Squonk 所说,这个答案对我没有帮助。但是感谢您的尝试。

以上是关于具有 ResultReceiver 和生命周期的 BroadcastReceiver的主要内容,如果未能解决你的问题,请参考以下文章

使用 Flyway 和 Spring Boot 迁移具有不同生命周期的多个模式

如何为具有生命周期'a的结构实现具有'静态生命周期的特征?

了解生命周期:最大生命周期和“静态”

具有持久 HTTP 连接的 IDbConnection 生命周期管理

具有不同生命周期的对象的 Scala 蛋糕模式

Flyway:如何支持清理具有相同生命周期的多个模式?