在活动之间共享数据的最佳方式是什么? [英] What's the best way to share data between activities?

查看:27
本文介绍了在活动之间共享数据的最佳方式是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个活动,它是整个应用程序中使用的主要活动,它有许多变量.我还有另外两个活动,我希望能够使用第一个活动的数据.现在我知道我可以做这样的事情:

I have one activity which is the main activity used throughout the app and it has a number of variables. I have two other activities which I would like to be able to use the data from the first activity. Now I know I can do something like this:

GlobalState gs = (GlobalState) getApplication();
String s = gs.getTestMe();

然而,我想分享很多变量,有些可能相当大,所以我不想像上面那样创建它们的副本.

However I want to share a lot of variables and some might be rather large so I don't want to be creating copies of them like above.

有没有办法不使用get和set方法直接获取和修改变量?我记得在 Google 开发网站上读过一篇文章,说不推荐这样做以提高 Android 上的性能.

Is there a way to directly get and change the variables without using get and set methods? I remember reading an article on the Google dev site saying this is not recommended for performance on Android.

推荐答案

这里是实现这一目标的最常见方法:

  • 在意图内发送数据
  • 静态字段
  • WeakReferences的HashMap
  • 持久化对象(sqlite、共享首选项、文件等)

TL;DR:有两种共享数据的方式:在意图的附加内容中传递数据或将其保存在其他地方.如果数据是基元、字符串或用户定义的对象:将其作为意图附加项的一部分发送(用户定义的对象必须实现 Parcelable).如果传递复杂对象,则将实例保存在其他地方的单例中,并从启动的活动中访问它们.

TL;DR: there are two ways of sharing data: passing data in the intent's extras or saving it somewhere else. If data is primitives, Strings or user-defined objects: send it as part of the intent extras (user-defined objects must implement Parcelable). If passing complex objects save an instance in a singleton somewhere else and access them from the launched activity.

有关如何以及为何实施每种方法的一些示例:

Some examples of how and why to implement each approach:

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("some_key", value);
intent.putExtra("some_other_key", "a value");
startActivity(intent);

关于第二个活动:

Bundle bundle = getIntent().getExtras();
int value = bundle.getInt("some_key");
String value2 = bundle.getString("some_other_key");

使用此方法如果您要传递原始数据或字符串.您还可以传递实现 Serializable 的对象.

Use this method if you are passing primitive data or Strings. You can also pass objects that implements Serializable.

虽然很诱人,但您在使用 Serializable 之前应该三思:它容易出错并且速度非常慢.所以一般来说:尽可能远离 Serializable.如果您想传递复杂的用户定义对象,请查看Parcelable 接口.它更难实现,但与 Serializable 相比有相当大的速度提升.

Although tempting, you should think twice before using Serializable: it's error prone and horribly slow. So in general: stay away from Serializable if possible. If you want to pass complex user-defined objects, take a look at the Parcelable interface. It's harder to implement, but it has considerable speed gains compared to Serializable.

可以通过将数据保存在内存中来在活动之间共享数据,因为在大多数情况下,两个活动都在同一进程中运行.

It is possible to share data between activities by saving it in memory given that, in most cases, both activities run in the same process.

注意:有时,当用户离开您的活动(没有退出)时,Android 可能会决定终止您的应用程序.在这种情况下,我遇到过这样的情况,其中 android 尝试使用在应用程序被终止之前提供的意图启动最后一个活动.在这种情况下,存储在单例(您的或 Application)中的数据将消失,可能会发生不好的事情.为了避免这种情况,您可以将对象持久化到磁盘或在使用它之前检查数据以确保其有效.

Note: sometimes, when the user leaves your activity (without quitting it), Android may decide to kill your application. In such scenario, I have experienced cases in which android attempts to launch the last activity using the intent provided before the app was killed. In this cases, data stored in a singleton (either yours or Application) will be gone and bad things could happen. To avoid such cases, you either persist objects to disk or check data before using it to make sure its valid.

有一个类来保存数据:

public class DataHolder {
  private String data;
  public String getData() {return data;}
  public void setData(String data) {this.data = data;}

  private static final DataHolder holder = new DataHolder();
  public static DataHolder getInstance() {return holder;}
}

来自启动的活动:

String data = DataHolder.getInstance().getData();

使用应用单例

应用程序单例是 android.app.Application 的一个实例,它是在应用程序启动时创建的.你可以通过扩展 Application 来提供一个自定义的:

Use application singleton

The application singleton is an instance of android.app.Application which is created when the app is launched. You can provide a custom one by extending Application:

import android.app.Application;
public class MyApplication extends Application {
  private String data;
  public String getData() {return data;}
  public void setData(String data) {this.data = data;}
}

在启动活动之前:

MyApplication app = (MyApplication) getApplicationContext();
app.setData(someData);

然后,从启动的活动:

MyApplication app = (MyApplication) getApplicationContext();
String data = app.getData();

静态字段

想法与单例基本相同,但在这种情况下,您提供对数据的静态访问:

Static fields

The idea is basically the same as the singleton, but in this case you provide static access to the data:

public class DataHolder {
  private static String data;
  public static String getData() {return data;}
  public static void setData(String data) {DataHolder.data = data;}
}

来自启动的活动:

String data = DataHolder.getData();

WeakReferences

的HashMap

相同的想法,但允许垃圾收集器删除未引用的对象(例如,当用户退出活动时):

HashMap of WeakReferences

Same idea, but allowing the garbage collector to removed unreferenced objects (e.g. when the user quits the activity):

public class DataHolder {
  Map<String, WeakReference<Object>> data = new HashMap<String, WeakReference<Object>>();

  void save(String id, Object object) {
    data.put(id, new WeakReference<Object>(object));
  }

  Object retrieve(String id) {
    WeakReference<Object> objectWeakReference = data.get(id);
    return objectWeakReference.get();
  }
}

在启动活动之前:

DataHolder.getInstance().save(someId, someObject);

来自启动的活动:

DataHolder.getInstance().retrieve(someId);

您可能需要也可能不需要使用 Intent 的 extras 传递对象 id.这完全取决于您的具体问题.

You may or may not have to pass the object id using the intent’s extras. It all depends on your specific problem.

这个想法是在启动其他活动之前将数据保存在磁盘中.

The idea is to save the data in disk before launching the other activity.

优点:您可以从其他位置启动 Activity,如果数据已经持久化,它应该可以正常工作.

Advantages: you can launch the activity from other places and, if the data is already persisted, it should work just fine.

缺点:它很麻烦并且需要更多时间来实施.需要更多的代码,因此有更多的机会引入错误.它也会慢很多.

Disadvantages: it’s cumbersome and takes more time to implement. Requires more code and thus more chance of introducing bugs. It will also be much slower.

一些持久化对象的方法包括:

Some of the ways to persist objects include:

这篇关于在活动之间共享数据的最佳方式是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆