什么是从一个服务线程中调用一个Android活动回来的首选方式(What is the prefer

2019-08-17 14:40发布

我目前正在开发具有以下需求的Android应用程序:

工作线程开始服务。 该线程做一些处理,需要从主活动调用,并提供一些异步回答同样的活动。

从活动调用的服务是很容易(的IBinder的东西)

我现在的问题是关于适当的服务实现回调。

我首先要添加一个android.os.Handler在活动和MyActivity.handleMessage(邮件)处理线程的anwers但这需要我给这个处理程序的参考服务。 当Android操作系统决定销毁/重建我的活动,以便发生例如由于取向的变化是什么? 是否因为它是在服务引用(间接)我的活动活路? 如果活动破坏/重建反正,会发生什么在我的服务处理器的参考?

我想我没有使用正确的方法回调从服务线程的活动,所以我想知道,如果有人可以点我做的正确方法。

TIA

Answer 1:

我更喜欢使用LocalBroadcastManager

下面是在你的代码的例子Activity

BroadcastReceiver localBroadcastReceiver = new BroadcastReceiver()
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        Log.d("BroadcastReceiver", "Message received " + intent.getAction());
        Log.d("BroadcaseReceiver", "Received data " + intent.getStringExtra("com.my.package.intent.EXTRA_DATA"));
    }
};

@Override
protected void onStart()
{
    super.onStart();
    final LocalBroadcastManager localBroadcastManager =
        LocalBroadcastManager.getInstance(this);
    final IntentFilter localFilter = new IntentFilter();
    localFilter.addAction("com.my.package.intent.ACTION_NAME_HERE");
    localBroadcastManager.registerReceiver(localBroadcastReceiver, localFilter);
}

@Override
protected void onStop()
{
    super.onStop();
    final LocalBroadcastManager localBroadcastManager =
        LocalBroadcastManager.getInstance(this);
    // Make sure to unregister!!
    localBroadcastManager.unregisterReceiver(localBroadcastReceiver);
}

要是在别的地方在你的代码库(如在后台线程完成):

final LocalBroadcastManager localBroadcastManager =
    LocalBroadcastManager.getInstance(context);
final Intent intent = new Intent("com.my.package.intent.ACTION_NAME_HERE")
intent.putExtra("com.my.package.intent.EXTRA_DATA", yourBackgroundData);
localBroadcastManager.sendBroadcast(intent);

你可以,当然,使用intent.putExtra添加任何额外的数据,或者使用多个动作来区分广播消息。



Answer 2:

我们已经通过集中的活动和服务之间的所有通信进行此Application类。 我们扩展了Application类,然后有方法有没有绑定到服务并接受回调。 有一个之间没有直接联系ActivityService在该架构中。

这种机制的好处是,你不必担心在活动过渡和活动死亡和娱乐解除绑定/重新绑定到服务。 该Application类管理这一切,并没有受到什么样的活动做。 该Application类接收所有回调,你需要有代码,还有以确定如何处理与回调做。 也许你会想一些数据存储在Application类,然后有新的数据可用,或者类似的东西通知活动。

另一种方法是让Service广播的回调。 在这种情况下,服务和活动之间的耦合是松散的,这样你就不会需要创建一个Handler中的活动,然后把它传递给Service 。 活动只需注册BroadcastReceiver S表示他们有兴趣的回调,或者你可以在清单管理此。



Answer 3:

一种解决方案,就像你说的,就是用MyActivity.handleMessage(消息)。 每当你的活动启动(或重启),你可能会尝试启动服务(以下简称“onBind”的东西你提到)。 如果该服务已在运行,没有任何的损害。 一旦绑定的东西做你告诉服务信使送答复。

为确保重新启动的处理,在你的onStop需要告诉服务来删除Messenger在它的“地方名单送答复”,这样不小心发送消息到现在已经不存在的使者。 当在onStart被称为重启的一部分,它会发送现已正确的使者。

显然,这需要该服务处理这个不知何故管理由它来发送,而没有信使将其发送到响应的情况。 无论是它拥有信息,直到为Messenger可用或它丢弃的信息,活动明确得到所有的状态信息,作为后续到绑定的东西它已在onStart完成。

另一种方法是让活动调查服务,每隔一段时间(10秒?)时,它知道有处理事情,看结果是否可用,然后停止轮询一旦所有的信息又回来了。



Answer 4:

对于异步服务电话,一个会通过在发起一个回调的参考,我会说。

回调是要由粘合线,这是这种方法的标准执行。

当然,它发起呼叫可以依靠的事实,活动的粘合线在其自身的进程运行。 所以它很容易要回从回调的主/ UI线程。

因此,如果回调需要处理主/ UI线程的东西,它只是使用

(new Handler(Looper.getMainLooper()).post()

其具有在执行代码时,它动态查找主/ UI线程的时间点的优点。 在另一方面,这还没有必要的,因为主/ UI线程不会改变,通过查看参考或者其他任何你可能手头的回调也将工作,所以找到它。



文章来源: What is the preferred way to call an Android Activity back from a Service thread