Android相当于NSNotificationCenter
在将iPhone应用程序移植到Android的过程中,我正在寻找在应用程序内进行通信的最佳方式。 意图似乎是要走的路,这是最好的(唯一)的select? 在性能和编码方面,NSUserDefaults看起来比Intents更轻。
我也应该添加我有一个应用程序的子类的状态,但我需要使另一个活动意识到一个事件。
你可以试试这个: http : //developer.android.com/reference/java/util/Observer.html
我发现的最好的等价物是LocalBroadcastManager ,它是Android支持包的一部分 。
从LocalBroadcastManager文档:
助手注册并发送Intents的广播到您的过程中的本地对象。 与使用sendBroadcast(Intent)发送全局广播相比,这具有许多优点:
- 您知道您正在播放的数据不会离开您的应用程序,因此不必担心泄露私人数据。
- 其他应用程序不可能将这些广播发送到您的应用程序,所以您不必担心有可能利用的安全漏洞。
- 这比通过系统发送全球广播更有效率。
当使用这个,你可以说一个Intent
是相当于一个NSNotification
。 这里是一个例子:
ReceiverActivity.java
监视名为"custom-event-name"
的事件的通知的活动。
@Override public void onCreate(Bundle savedInstanceState) { ... // Register to receive messages. // This is just like [[NSNotificationCenter defaultCenter] addObserver:...] // We are registering an observer (mMessageReceiver) to receive Intents // with actions named "custom-event-name". LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("custom-event-name")); } // Our handler for received Intents. This will be called whenever an Intent // with an action named "custom-event-name" is broadcasted. private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // Get extra data included in the Intent String message = intent.getStringExtra("message"); Log.d("receiver", "Got message: " + message); } }; @Override protected void onDestroy() { // Unregister since the activity is about to be closed. // This is somewhat like [[NSNotificationCenter defaultCenter] removeObserver:name:object:] LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver); super.onDestroy(); }
SenderActivity.java
发送/广播通知的第二个活动。
@Override public void onCreate(Bundle savedInstanceState) { ... // Every time a button is clicked, we want to broadcast a notification. findViewById(R.id.button_send).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { sendMessage(); } }); } // Send an Intent with an action named "custom-event-name". The Intent sent should // be received by the ReceiverActivity. private void sendMessage() { Log.d("sender", "Broadcasting message"); Intent intent = new Intent("custom-event-name"); // You can also include some extra data. intent.putExtra("message", "This is my message!"); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); }
使用上面的代码,每次单击buttonR.id.button_send
,Intent都会被广播, mMessageReceiver
ReceiverActivity
的mMessageReceiver
ReceiverActivity
。
debugging输出应该如下所示:
01-16 10:35:42.413: D/sender(356): Broadcasting message 01-16 10:35:42.421: D/receiver(356): Got message: This is my message!
你可以使用这个: http : //developer.android.com/reference/android/content/BroadcastReceiver.html ,它给出了类似的行为。
您可以通过Context.registerReceiver(BroadcastReceiver,IntentFilter)以编程方式注册接收者,它将捕获通过Context.sendBroadcast(Intent)发送的意图。
但请注意,如果接收者的活动(上下文)已暂停,接收者将不会收到通知。
我发现使用Guava lib的EventBus是在组件之间进行发布 – 订阅式通信的最简单的方式,而不需要组件彼此显式注册
请参阅https://code.google.com/p/guava-libraries/wiki/EventBusExplained上的示例;
// Class is typically registered by the container. class EventBusChangeRecorder { @Subscribe public void recordCustomerChange(ChangeEvent e) { recordChange(e.getChange()); } // somewhere during initialization eventBus.register(this); } // much later public void changeCustomer() { eventBus.post(new ChangeEvent("bla bla") ); }
你可以简单地在Android Studio上添加一个依赖到你的build.gradle:
compile 'com.google.guava:guava:17.0'
这里有一些类似于@Shiki的答案,但是从iOS开发者和通知中心的angular度来看。
首先创build一些NotificationCenter服务:
public class NotificationCenter { public static void addObserver(Context context, NotificationType notification, BroadcastReceiver responseHandler) { LocalBroadcastManager.getInstance(context).registerReceiver(responseHandler, new IntentFilter(notification.name())); } public static void removeObserver(Context context, BroadcastReceiver responseHandler) { LocalBroadcastManager.getInstance(context).unregisterReceiver(responseHandler); } public static void postNotification(Context context, NotificationType notification, HashMap<String, String> params) { Intent intent = new Intent(notification.name()); // insert parameters if needed for(Map.Entry<String, String> entry : params.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); intent.putExtra(key, value); } LocalBroadcastManager.getInstance(context).sendBroadcast(intent); } }
然后,你还需要一些枚举types来保证string编码时的错误 – (NotificationType):
public enum NotificationType { LoginResponse; // Others }
这里是使用(添加/删除观察者)例如在活动中:
public class LoginActivity extends AppCompatActivity{ private BroadcastReceiver loginResponseReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // do what you need to do with parameters that you sent with notification //here is example how to get parameter "isSuccess" that is sent with notification Boolean result = Boolean.valueOf(intent.getStringExtra("isSuccess")); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); //subscribe to notifications listener in onCreate of activity NotificationCenter.addObserver(this, NotificationType.LoginResponse, loginResponseReceiver); } @Override protected void onDestroy() { // Don't forget to unsubscribe from notifications listener NotificationCenter.removeObserver(this, loginResponseReceiver); super.onDestroy(); } }
最后是我们如何通过一些callback或rest服务或其他方式向NotificationCenter发送通知:
public void loginService(final Context context, String username, String password) { //do some async work, or rest call etc. //... //on response, when we want to trigger and send notification that our job is finished HashMap<String,String> params = new HashMap<String, String>(); params.put("isSuccess", String.valueOf(false)); NotificationCenter.postNotification(context, NotificationType.LoginResponse, params); }
就是这样,欢呼!
你可以使用弱引用。
这样你可以自己pipe理记忆,并随意添加和删除观察者。
添加这些参数时,请添加这些参数 – 将该上下文从要添加到其中的活动转换到空接口,添加通知名称,然后调用该方法以运行接口。
运行接口的方法有一个叫做run的函数来返回你正在传递的数据
public static interface Themethodtorun { void run(String notification_name, Object additional_data); }
创build一个调用具有空接口的引用的观察类。 还要从addobserver中传递的上下文构造你的Themethodtorun接口。
将观察添加到数据结构。
要调用它将是相同的方法,但是您只需要在数据结构中find特定的通知名称,请使用Themethodtorun.run(notification_name,data)。
这将发送一个callback,以便您创build具有特定通知名称的观察者。 不要忘了把它们删除,当你完成!
这是弱引用的好参考。
http://learningviacode.blogspot.co.nz/2014/02/weak-references-in-java.html
我正在把这段代码上传到github。 保持睁大眼睛!