当前位置: 首页 > 面试题库 >

在活动之间共享数据的最佳方法是什么?

雷浩思
2023-03-14
问题内容

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

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

但是我想共享很多变量,有些可能很大,所以我不想像上面那样创建它们的副本。

有没有一种方法可以直接获取和更改变量而无需使用get和set方法?我记得在Google开发者网站上读过一篇文章,建议不要在Android上使用此功能。


问题答案:

这里是实现此目的的最常用方法的汇编:

  • Send data inside intent
  • Static fields
  • HashMap of WeakReferences
  • Persist objects (sqlite, share preferences, file, etc.)

TL; DR:有两种共享数据的方式:在Intent的Extras中传递数据或将其保存在其他地方。如果数据是原始数据,字符串或用户定义的对象:请将其作为附加意图的一部分发送(用户定义的对象必须实现Parcelable)。如果传递复杂对象,则将实例保存在其他位置的一个实例中,然后从启动的活动中访问它们。

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

在意图内发送数据

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

如果要传递原始数据或String,请使用此方法。你还可以传递实现的对象Serializable

尽管很诱人,但在使用之前你应该三思而后行Serializable:它容易出错并且非常慢。因此,一般而言:尽可能远离Serializable。如果要传递复杂的用户定义对象,请查看Parcelableinterface。实施起来比较困难,但与相比,它具有可观的速度提升Serializable

共享数据而不保留到磁盘
考虑到大多数情况下两个活动都在同一进程中运行,可以通过将活动保存在内存中来共享活动之间的数据。

注意:有时候,当用户离开你的活动(不退出活动)时,Android可能会决定终止你的应用程序。在这种情况下,我经历了一些案例,其中android尝试使用应用程序被杀死之前提供的意图启动最后一个活动。在这种情况下,存储在单例(你的或Application)中的数据将消失,并且可能会发生不良情况。为避免这种情况,你可以将对象持久保存到磁盘上,或者在使用数据以确保其有效之前检查数据。

Use a singleton class

有一个类来保存数据:

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:

import android.app.Application;
public class MyApplication extends Applicathtml" target="_blank">ion {
  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();

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

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();
的HashMap WeakReferences

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

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

你可能需要也可能不必使用意图的附加对象传递对象ID。这完全取决于你的特定问题。

将对象持久化到磁盘
这个想法是在启动其他活动之前将数据保存在磁盘中。

优点:你可以从其他地方启动活动,如果数据已经保存,则应该可以正常工作。

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



 类似资料:
  • 有没有人知道Docker中容器之间共享数据库的最佳实践是什么? 我的意思是我想在Docker中创建多个容器。然后,这些容器将以相同的身份在相同的数据库上执行CRUD。 到目前为止,我有两个想法。一种是创建一个单独的容器来运行数据库。另一种方法是直接在安装Docker的主机上安装数据库。

  • 我想验证一个发出请求的用户。为此,我有两个过滤器:AuthenticationFilter和authorizationfilter。AuthenticationFilter从请求中提取令牌并从数据库中查找用户。AuthorizationFilter检查该用户(由上一个筛选器检索)是否具有必要的权限。我有两个可能的解决方案,想知道每一个的利弊,我应该使用哪一个。我还需要访问实际业务逻辑中的用户。我的

  • 问题内容: 我在Windows机器上有一个访问数据库,必须将其导入到Linux Web服务器上的mysql中。目前,访问dabatbase表已导出为文本文件,并通过ftp自动复制,然后加载到mysql中。 有没有更好的方法可以执行此操作,也许使用ODBC连接或其他方法? 限制复制已经存在的信息的最佳方法是什么,即仅传输访问数据库中的记录而mysql中尚未的记录。 访问数据库是由另一个程序处理的,最

  • 问题内容: 当您有多个都使用同一组JAR库的项目时,在每个项目中一遍又一遍地包含相同的JAR太麻烦了。如果我正在从事20个不同的项目,那么我宁愿没有20个完全相同的JAR文件。使所有这些项目(以及新项目)引用同一组JAR的最佳方法是什么? 我有一些想法,但每个想法都有一些缺点: 将所有JAR放在一个文件夹中,并使每个项目都在该文件夹中显示。 使用Eclipse创建一个“用户库”,并使每个项目都引用

  • 问题内容: 我已经和Docker玩了一段时间,在处理持久性数据时继续寻找相同的问题。 我创建我的文件并公开一个卷,或使用它[在容器中安装主机文件夹]。 我应该对主机上的共享卷应用什么权限? 我可以想到两种选择: 到目前为止,我已经授予所有人读取/写入访问权限,因此我可以从Docker容器写入该文件夹。 将用户从主机映射到容器,以便我可以分配更多的细化权限。不确定这是否可能,但尚未找到很多相关信息。

  • 我使用Docker已经有一段时间了,并且在处理持久数据时不断发现相同的问题。 我创建并公开卷,或者使用在容器中装入主机文件夹。 我应该对主机上的共享卷应用什么权限? 我能想到两个选择: > 到目前为止,我已经为每个人提供了读/写访问权限,因此我可以从Docker容器写入文件夹。 将用户从主机映射到容器中,这样我就可以分配更多的粒度权限。不确定这是可能的,但还没有找到很多关于它。到目前为止,我所能做