为什么LocalBroadcastManager不能工作而不是Context.registerReceiver?

问题描述 投票:9回答:3

我必须为这个应用程序实现一个功能,包括ActivityService在后台工作(它实现Service,而不是IntentService)。

我在互联网上经历了一些应该工作的教程,他们都使用LocalBroadcastManager,顺便说一句是Android推荐的:

如果您不需要跨应用程序发送广播,请考虑使用此类与LocalBroadcastManager而不是下面描述的更一般的工具。

我真的失去了一天,找出问题为什么它对我不起作用:它只有在我使用Context.sendBroadcast()时才有效。和Context.registerReceiver()而不是LocalBroadcastManager方法。

现在我的应用程序正在运行,但我觉得我反对最佳做法,我不知道为什么。任何想法为什么会发生?

编辑:

在我写完这个问题后,我进一步研究了这个问题。 LocalBroadcastManager通过Singleton工作,我们应该称之为LocalBroadcastManager.getInstance(this).method()。我记录了两个实例(在ActivityService中),它们有不同的内存地址。现在我来到另一个问题,不应该ServiceContextActivity相同吗?从this article一个服务在主线程上运行,因此我认为Context将是相同的。

有什么想法吗? (对不起,长篇文章)

代码示例:

为MyService

public class MyService extends Service {

...

// When an event is triggered, sends a broadcast

Intent myIntent = new Intent(MainActivity.MY_INTENT);
myIntent.putExtra("myMsg","msg");
sendBroadcast(myIntent);

// Previously I was trying:
// LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(myIntent);

}

MyActivity

public class MainActivity {

...

private BroadcastReceiver messageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) { 
            Log.d("onReceive", "received!");
            // TODO something
        }
    };

@Override
protected void onResume() {
    super.onResume();
    registerReceiver(messageReceiver, new IntentFilter(MY_INTENT));
    // Previously I was trying:
    // LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(messageReceiver, new IntentFilter(MY_INTENT));
}
}
android service broadcastreceiver broadcast intentservice
3个回答
8
投票

我从来没有使用过LocalBroadcastManager,但听起来你必须使用register your receiver on there(即lbm.registerReceiver(...),而不是mycontext.registerReceiver(...))。你在做吗?

现在我来到另一个问题,服务是否应该与调用它的Activity具有相同的Context?从本文开始,服务在主线程上运行,因此我认为Context将是相同的。

Context类与线程无关。实际上,Service和Activity都是Context的(间接)子类 - 所以它们是他们自己的上下文! 这就是为什么你可以使用“this”作为上下文。

但无论你发送到LocalBroadcastManager.getInstance()的哪个上下文,你应该得到exact same LBM instance。我想不出你有什么理由 - 除非你在不同的进程中运行Activity和Service?


10
投票

宣言:

private BroadcastReceiver receiver;

初始化:

receiver = new BroadcastReceiver()
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        //todo
    }
};

注册:

LocalBroadcastManager.getInstance(context).registerReceiver(receiver, new IntentFilter("RECEIVER_FILTER"));

context可以是任何类型的Context,您可以使用应用程序上下文。

注销:

LocalBroadcastManager.getInstance(context).unregisterReceiver(receiver);

广播:

Intent intent = new Intent("RECEIVER_FILTER");
intent.putExtra("EXTRA", someExtra);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);

5
投票

检查你的服务和活动是否在不同的进程中运行,LocalBroadcastManager不能在不同的进程中应用。(你应该在AndroidManifest.xml文件中看到它)

© www.soinside.com 2019 - 2024. All rights reserved.