在将iPhone应用程序移植到Android的过程中,我正在寻找在应用程序中进行通信的最佳方法。意图似乎是最好的选择,这是最好的(唯一)选项吗? NsuserDefaults的重量似乎比性能和编码方面的意图重得多。

我还应该补充说,我有一个国家的应用程序子类,但是我需要让另一个活动意识到事件。

有帮助吗?

其他提示

我发现的最好的等效是 LocalBroadcastManager 哪个是 Android支持包.

来自LocalBroadcastManager文档:

助手在您的流程中注册并将意图广播发送给本地对象。与发送SendBroadcast(意图)的全局广播相比,这具有许多优势:

  • 您知道您正在广播的数据不会离开您的应用程序,因此不必担心泄漏私人数据。
  • 其他应用程序不可能将这些广播发送到您的应用程序,因此您不必担心拥有可以利用的安全孔。
  • 它比通过系统发送全球广播更有效。

使用此过程时,您可以说 Intent 相当于 NSNotification. 。这是一个示例:

接收者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();
}

enderActivity.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);
}

使用上面的代码,每次按钮 R.id.button_send 单击,播放意图,并收到 mMessageReceiverReceiverActivity.

调试输出应该看起来像这样:

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! 

这与@shiki的答案相似,但是从iOS开发人员和通知中心的角度来看。

首先创建某种通知中心服务:

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

然后,您还需要一些枚举类型才能解决使用字符串编码的错误 - (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();
    }
}

最终,我们如何将通知从某些回调或休息服务或其他方式发布到通知中心:

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

就是这样,欢呼!

您可以使用此: 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") );
} 

您可以通过在build.gradle中添加依赖性来简单地在Android Studio上添加此lib:

compile 'com.google.guava:guava:17.0'

您可以使用弱参考。

这样,您可以自己管理内存,并随意添加和删除观察者。

当您添加这些参数时,将其添加到空界面中的活动中时,添加通知名称,然后调用运行接口的方法。

运行接口的方法将具有称为运行的函数,以返回您正在传递的数据

public static interface Themethodtorun {
        void run(String notification_name, Object additional_data);
    }

创建一个观察类,该类别调用带有空接口的参考。还可以从Addobserver中传递的上下文中构造您的theodtorun接口。

将观察值添加到数据结构中。

要调用它是相同的方法,但是您需要做的就是在数据结构中找到特定的通知名称,请使用themethodtorun.run(notification_name,data)。

这将向您创建具有特定通知名称的观察者的位置发送回调。完成后不要忘记将它们删除!

这是弱参考文献的好参考。

http://learningviacode.blogspot.co.nz/2014/02/weak-references-in-java.html

我正在将此代码上传到GitHub。睁开眼睛!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top