具有 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 交互),但即便如此,AsyncTask
在Service
中被破坏的可能性也要小得多。在Activity
.
正如@Squonk 所说,这个答案对我没有帮助。但是感谢您的尝试。以上是关于具有 ResultReceiver 和生命周期的 BroadcastReceiver的主要内容,如果未能解决你的问题,请参考以下文章
使用 Flyway 和 Spring Boot 迁移具有不同生命周期的多个模式