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

时间:2015-04-20 19:30:45

标签: android service broadcastreceiver broadcast intentservice

我必须为此应用实施一项功能,其中包含ActivityService在后​​台工作(它实现Service,而不是IntentService)。< / p>

我在互联网上浏览了一些应该有用的教程,他们都使用了LocalBroadcastManager,顺便说一下,这是Android推荐的:

  

如果您不需要跨应用程序发送广播,请考虑   使用此类与LocalBroadcastManager而不是更多   一般设施如下所述。

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

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

修改

在我写完这个问题后,我进一步研究了这个问题。 LocalBroadcastManager通过Singleton工作,我们应该调用LocalBroadcastManager.getInstance(this).method()。我记录了两个实例(在ActivityService中)并且它们具有不同的内存地址。 现在我遇到了另一个问题,Service不应该与调用它的Context具有相同的Activity吗?从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));
}
}

3 个答案:

答案 0 :(得分:9)

声明:

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);

答案 1 :(得分:8)

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

  

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

Context类与线程无关。实际上,Service和Activity都是Context的(间接)子类 - 所以他们是他们自己的上下文!
这就是为什么你可以使用&#34;这个&#34;作为一个背景。

但无论您向LocalBroadcastManager.getInstance()发送哪个上下文,都应该将exact same LBM instance取出。我无法想到你不会有任何理由 - 除非你在不同的流程中运行活动和服务?

答案 2 :(得分:5)

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