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

时间:2021-05-23 20:58:19

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.

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

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.

有没有一种不用get和set方法直接获取和更改变量的方法?我记得读过一篇关于谷歌开发网站的文章,说这是不推荐使用Android的。

13 个解决方案

#1


427  

Here a compilation of most common ways to achieve this:

这里汇集了实现这一目标的最常见方法:

  • Send data inside intent
  • 在发送数据的意图
  • Static fields
  • 静态字段
  • HashMap of WeakReferences
  • HashMap weakreference引用的
  • Persist objects (sqlite, share preferences, file, etc.)
  • 持久对象(sqlite、共享首选项、文件等)

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.

有两种共享数据的方法:在意图的附加部分中传递数据,或者将数据保存到其他地方。如果数据是原语、字符串或用户定义的对象:将其作为intent extras(用户定义的对象必须实现Parcelable)的一部分发送。如果传递复杂对象,将实例保存在其他地方,并从启动的活动中访问它们。

Some examples of how and why to implement each approach:

关于如何和为什么执行每一种方法的一些例子:

Send data inside intents

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

On the second activity:

在第二个活动:

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

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

如果要传递原始数据或字符串,请使用此方法。您还可以传递实现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.

尽管诱人,在使用Serializable之前,您应该三思:它很容易出错,而且速度非常慢。一般来说,如果可能的话,远离可串行化。如果您想要传递复杂的用户定义的对象,请查看Parcelable接口。它很难实现,但是与Serializable属性相比,它具有相当大的速度增益。

Share data without persisting to disk

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.

在活动之间共享数据是可能的,因为在大多数情况下,两个活动都在同一个进程中运行。

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.

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

Use a singleton class

Have a class to hold the data:

有一个类来保存数据:

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

From the launched activity:

发起的活动:

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

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:

单例应用程序是android.app的一个实例。当应用程序启动时创建的应用程序。您可以通过扩展应用程序来提供定制的:

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

Before launching the activity:

之前推出的活动:

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

Then, from the launched activity:

然后,从启动的活动:

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 String setData(String data) {DataHolder.data = data;}
}

From the launched activity:

发起的活动:

String data = DataHolder.getData();

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

Before launching the activity:

之前推出的活动:

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

From the launched activity:

发起的活动:

DataHolder.getInstance().retrieve(someId);

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

您可能需要或不需要使用intent的额外功能传递对象id。这完全取决于你的具体问题。

Persist objects to disk

The idea is to save the data in disk before launching the other 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.

缺点:它很麻烦,需要更多的时间来实现。需要更多的代码,从而有更多的机会引入bug。它也会慢得多。

Some of the ways to persist objects include:

保存对象的一些方法包括:

#2


22  

What you can use:

你可以使用:

  1. passing data between activities (like Cristian said)
  2. 在活动之间传递数据(如克里斯蒂安所说)
  3. using a class with a lot of static variables (so you can call them without an instance of the class and without using getter/setter)
  4. 使用具有许多静态变量的类(这样您就可以在不使用类实例和不使用getter/setter的情况下调用它们)
  5. Using a database
  6. 使用数据库
  7. Shared Preferences
  8. 共同的喜好

What you choose depends on your needs. Probably you will use more than one way when you have "a lot of"

你选择什么取决于你的需要。当你有很多

#3


15  

Do what google commands you to do! here: http://developer.android.com/resources/faq/framework.html#3

做谷歌命令你做的事!:http://developer.android.com/resources/faq/framework.html # 3

  • Primitive Data Types
  • 原始数据类型
  • Non-Persistent Objects
  • 非持久化对象
  • Singleton class - my favorite :D
  • 单例类-我最喜欢的:D
  • A public static field/method
  • 一个公共静态字段/方法
  • A HashMap of WeakReferences to Objects
  • 对象弱引用的HashMap
  • Persistent Objects (Application Preferences, Files, contentProviders, SQLite DB)
  • 持久性对象(应用程序首选项、文件、内容提供程序、SQLite DB)

#4


14  

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

“然而,我想要分享很多变量,有些可能相当大,所以我不想在上面创建它们的副本。”

That doesn't make a copy (especially with String, but even objects are pass by value of the reference, not the object itself, and getter's like that are fine to use -- arguably better to use than other means because they are common and well understood). The older "performance myths," such as not using getters and setters, still have some value, but have also been updated in the docs.

这并不是复制(特别是使用String时,甚至连对象都是通过引用的值传递的,而不是对象本身,而getter也很好使用——可以说比其他方法更好使用,因为它们是通用的,也很容易理解)。旧的“性能神话”,比如不使用getter和setter,仍然有一些价值,但也在文档中得到了更新。

But if you don't want to do that, you could also just make the variables public or protected in GlobalState and access them directly. And, you can make a static singleton as the Application object JavaDoc indicates:

但如果你不想这样做,你也可以将变量设置为公共的或受保护的,直接访问它们。并且,您可以创建一个静态的单例对象,如应用程序对象JavaDoc所示:

There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton.

通常不需要子类化应用程序。在大多数情况下,静态单例可以以更模块化的方式提供相同的功能。如果您的单例需要一个全局上下文(例如注册广播接收器),那么在第一次构造单例时,可以给检索它的函数一个上下文,这个上下文在内部使用context . getapplicationcontext()。

Using Intent data, as other answers here note is another way to pass data, but it's usually used for smaller data and simple types. You can pass larger/more complex data, but it's more involved than just using a static singleon. The Application object is still my personal favorite for sharing larger/more complex non persistent data between Android application components though (because it has a well defined lifecycle in an Android app).

使用意图数据(这里的其他答案)是传递数据的另一种方式,但它通常用于较小的数据和简单的类型。您可以传递更大/更复杂的数据,但这比使用静态singleon要复杂得多。应用程序对象仍然是我个人最喜欢在Android应用程序组件之间共享更大/更复杂的非持久性数据的对象(因为它在Android应用程序中有一个定义良好的生命周期)。

Also, as others have noted, if the data gets very complex and needs to be persistent then you can use SQLite or the filesystem too.

另外,正如其他人所指出的,如果数据变得非常复杂并且需要持久,那么您也可以使用SQLite或文件系统。

#5


7  

You could extend the Application class and tag on any objects you want there, they are then available anywhere in your application

您可以在任何需要的对象上扩展应用程序类和标记,然后在应用程序的任何地方都可以使用它们

#6


2  

Using the hashmap of weak reference approach, described above, and in http://developer.android.com/guide/faq/framework.html seems problematic to me. How are entire entries reclaimed, not just the map value? What scope do you allocate it in? As the framework is in control of the Activity lifecycle, having one of the participating Activities own it risks runtime errors when the owner is destroyed in advance of its clients. If the Application owns it, some Activity must explicitly remove the entry to avoid the hashmap from holding on to entries with a valid key and a potentially garbaged collected weak reference. Furthermore, what should a client do when the value returned for a key is null?

使用上面描述的弱引用方法的hashmap,以及http://developer.android.com/guide/faq/framework.html,对我来说似乎是有问题的。如何回收整个条目,而不仅仅是映射值?你在什么范围内分配它?由于框架控制活动生命周期,当所有者在其客户端之前被破坏时,让一个参与的活动拥有它的运行时错误风险。如果应用程序拥有该条目,那么某些活动必须显式地删除条目,以避免hashmap持有具有有效键和可能被加错的弱引用的条目。此外,当为键返回的值为空时,客户端应该做什么?

It seems to me that a WeakHashMap owned by the Application or within a singleton is a better choice. An value in the map is accessed via a key object, and when no strong references to the key exist (i.e. all Activities are done with the key and what it maps to), GC can reclaim the map entry.

在我看来,应用程序或单例模式拥有的弱hashmap是更好的选择。通过键对象访问映射中的值,并且当不存在对键的强引用时(也就是说,所有的活动都使用键和它映射到的内容),GC可以回收映射条目。

#7


1  

Well I have a few ideas, but I don't know if they are what your looking for.

我有一些想法,但我不知道它们是不是你想要的。

You could use a service that holds all of the data and then just bind your activities to the service for data retrival.

您可以使用一个保存所有数据的服务,然后将您的活动绑定到服务以进行数据检索。

Or package your data into a serializable or parcelable and attach them to a bundle and pass the bundle between activities.

或者将数据打包成可序列化或可分割的,并将它们附加到一个包中,并在活动之间传递该包。

This one may not be at all what your looking for, but you could also try using a SharedPreferences or a preference in general.

这个选项可能完全不是您想要的,但是您也可以尝试使用共享的首选项或一般的首选项。

Either way let me know what you decide.

不管怎样,让我知道你的决定。

#8


1  

Assuming you are calling activity two from activity one using an Intent.
You can pass the data with the intent.putExtra(),

假设您从活动一调用活动2,使用意图。您可以使用intent.putExtra()传递数据,

Take this for your reference. Sending arrays with Intent.putExtra

拿这个作为你的参考。发送数组与Intent.putExtra

Hope that's what you want.

希望这就是你想要的。

#9


1  

If your intention is to call other Activities from the current Activity, you should use Intents. Your focus could be less on persisting data than on sharing it on an as-needed basis.

如果您的意图是从当前活动调用其他活动,您应该使用意图。您的重点可能不是持久化数据,而是根据需要共享数据。

However, if you really need to persist these values then you could persist them in some kind of structured text file or database on local storage. A properties file, XML file, or JSON file could store your data and be easily parsed during activity creation. Don't forget also that you have SQLite on all Android devices, so you could store them in a database table. You could also use a Map to store key-value pairs and serialize the map to local storage, but this might be too cumbersome to be useful for simple data structures.

但是,如果您确实需要持久化这些值,那么您可以将它们保存在本地存储上的某种结构化文本文件或数据库中。属性文件、XML文件或JSON文件可以存储您的数据,并且在创建活动时很容易解析。不要忘记,在所有Android设备上都有SQLite,因此可以将它们存储在数据库表中。您还可以使用映射来存储键-值对并将映射序列化到本地存储,但是这对于简单的数据结构来说可能太麻烦了。

#10


1  

All of the aforementioned answers are great... I'm just adding one no one had mentioned yet about persisting data through activities and that is to use the built in android SQLite database to persist relevant data... In fact you can place your databaseHelper in the application state and call it as needed throughout the activates.. Or just make a helper class and make the DB calls when needed... Just adding another layer for you to consider... But all of the other answers would suffice as well.. Really just preference

以上的答案都很棒……我只是添加了一个还没有人提到过的通过活动来保存数据的方法,那就是使用android SQLite数据库来保存相关数据……实际上,您可以将databaseHelper设置为应用程序状态,并在整个激活过程中根据需要调用它。或者只是创建一个helper类,在需要的时候进行DB调用……只要再加一层给你考虑……但是所有其他的答案也足够了。只是偏好

#11


1  

Sharing data between activites example passing an email after login

在activites示例之间共享数据,在登录后传递电子邮件

"email" is the name that can be used to reference the value on the activity that's being requested

“email”是可以用来引用被请求活动的值的名称

1 Code on the login page

1登录页面上的代码

Intent openLoginActivity = new Intent(getBaseContext(), Home.class);
    openLoginActivity.putExtra("email", getEmail);

2 code on the home page

主页上的2个代码

Bundle extras = getIntent().getExtras();
    accountEmail = extras.getString("email");

#12


1  

There are various way to share data between activities

活动之间有各种共享数据的方法

1: Passing data between activities using Intent

1:使用意图在活动之间传递数据

Intent intent=new Intent(this, desirableActivity.class);
intent.putExtra("KEY", "Value");
startActivity(intent)

2: Using static keyword , define variable as public static and use any where in project

2:使用static关键字,将变量定义为public static,并在项目中的任何地方使用

      public static int sInitialValue=0;

use anywhere in project using classname.variableName;

在项目的任何地方使用类名。

3: Using Database

3:使用数据库

but its bit lengthy process, you have to use query for inserting data and iterate data using cursor when need. But there are no chance of losing data without cleaning cache.

但是它的冗长过程,您必须使用查询来插入数据并在需要时使用游标迭代数据。但是,如果不清理缓存,就不可能丢失数据。

4: Using shared Preferences

4:使用共享的偏好

much easier than database. but there is some limitation you can not save ArrayList ,List and custome objects.

更容易比数据库。但是存在一些限制,您不能保存ArrayList、List和custome对象。

5: Create getter setter in Aplication class and access any where in project.

5:在Aplication类中创建getter setter,并访问项目中的任何位置。

      private String data;
      public String getData() {
          return data;
      }

      public void setData(String data) {
          this.data = data;
      }

here set and get from activities

这里设置并从活动中获取

         ((YourApplicationClass)getApplicationContext()).setData("abc"); 

         String data=((YourApplicationClass)getApplicationContext()).getData();  

#13


0  

And if you wanna work with data object, this two implements very important:

如果你想处理数据对象,这两个实现非常重要:

Serializable vs Parcelable

  • Serializable is a marker interface, which implies the user cannot marshal the data according to their requirements. So when object implements Serializable Java will automatically serialize it.
  • Serializable(可串行化的)是一个标记接口,它意味着用户不能根据需求对数据进行编组。因此,当对象实现Serializable Java将自动序列化它。
  • Parcelable is android own serialization protocol. In Parcelable, developers write custom code for marshaling and unmarshaling. So it creates less garbage objects in comparison to Serialization
  • Parcelable是android自己的序列化协议。在Parcelable中,开发人员编写用于封送和反封送的自定义代码。因此,与序列化相比,它创建的垃圾对象更少
  • The performance of Parcelable is very high when comparing to Serializable because of its custom implementation It is highly recommended to use Parcelable implantation when serializing objects in android.
  • 由于Parcelable的自定义实现,与Serializable相比,它的性能非常高,因此强烈建议在android中序列化对象时使用Parcelable嵌入。

public class User implements Parcelable

公共类用户实现可共享

check more in here

检查更多的在这里

#1


427  

Here a compilation of most common ways to achieve this:

这里汇集了实现这一目标的最常见方法:

  • Send data inside intent
  • 在发送数据的意图
  • Static fields
  • 静态字段
  • HashMap of WeakReferences
  • HashMap weakreference引用的
  • Persist objects (sqlite, share preferences, file, etc.)
  • 持久对象(sqlite、共享首选项、文件等)

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.

有两种共享数据的方法:在意图的附加部分中传递数据,或者将数据保存到其他地方。如果数据是原语、字符串或用户定义的对象:将其作为intent extras(用户定义的对象必须实现Parcelable)的一部分发送。如果传递复杂对象,将实例保存在其他地方,并从启动的活动中访问它们。

Some examples of how and why to implement each approach:

关于如何和为什么执行每一种方法的一些例子:

Send data inside intents

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

On the second activity:

在第二个活动:

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

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

如果要传递原始数据或字符串,请使用此方法。您还可以传递实现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.

尽管诱人,在使用Serializable之前,您应该三思:它很容易出错,而且速度非常慢。一般来说,如果可能的话,远离可串行化。如果您想要传递复杂的用户定义的对象,请查看Parcelable接口。它很难实现,但是与Serializable属性相比,它具有相当大的速度增益。

Share data without persisting to disk

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.

在活动之间共享数据是可能的,因为在大多数情况下,两个活动都在同一个进程中运行。

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.

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

Use a singleton class

Have a class to hold the data:

有一个类来保存数据:

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

From the launched activity:

发起的活动:

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

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:

单例应用程序是android.app的一个实例。当应用程序启动时创建的应用程序。您可以通过扩展应用程序来提供定制的:

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

Before launching the activity:

之前推出的活动:

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

Then, from the launched activity:

然后,从启动的活动:

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 String setData(String data) {DataHolder.data = data;}
}

From the launched activity:

发起的活动:

String data = DataHolder.getData();

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

Before launching the activity:

之前推出的活动:

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

From the launched activity:

发起的活动:

DataHolder.getInstance().retrieve(someId);

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

您可能需要或不需要使用intent的额外功能传递对象id。这完全取决于你的具体问题。

Persist objects to disk

The idea is to save the data in disk before launching the other 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.

缺点:它很麻烦,需要更多的时间来实现。需要更多的代码,从而有更多的机会引入bug。它也会慢得多。

Some of the ways to persist objects include:

保存对象的一些方法包括:

#2


22  

What you can use:

你可以使用:

  1. passing data between activities (like Cristian said)
  2. 在活动之间传递数据(如克里斯蒂安所说)
  3. using a class with a lot of static variables (so you can call them without an instance of the class and without using getter/setter)
  4. 使用具有许多静态变量的类(这样您就可以在不使用类实例和不使用getter/setter的情况下调用它们)
  5. Using a database
  6. 使用数据库
  7. Shared Preferences
  8. 共同的喜好

What you choose depends on your needs. Probably you will use more than one way when you have "a lot of"

你选择什么取决于你的需要。当你有很多

#3


15  

Do what google commands you to do! here: http://developer.android.com/resources/faq/framework.html#3

做谷歌命令你做的事!:http://developer.android.com/resources/faq/framework.html # 3

  • Primitive Data Types
  • 原始数据类型
  • Non-Persistent Objects
  • 非持久化对象
  • Singleton class - my favorite :D
  • 单例类-我最喜欢的:D
  • A public static field/method
  • 一个公共静态字段/方法
  • A HashMap of WeakReferences to Objects
  • 对象弱引用的HashMap
  • Persistent Objects (Application Preferences, Files, contentProviders, SQLite DB)
  • 持久性对象(应用程序首选项、文件、内容提供程序、SQLite DB)

#4


14  

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

“然而,我想要分享很多变量,有些可能相当大,所以我不想在上面创建它们的副本。”

That doesn't make a copy (especially with String, but even objects are pass by value of the reference, not the object itself, and getter's like that are fine to use -- arguably better to use than other means because they are common and well understood). The older "performance myths," such as not using getters and setters, still have some value, but have also been updated in the docs.

这并不是复制(特别是使用String时,甚至连对象都是通过引用的值传递的,而不是对象本身,而getter也很好使用——可以说比其他方法更好使用,因为它们是通用的,也很容易理解)。旧的“性能神话”,比如不使用getter和setter,仍然有一些价值,但也在文档中得到了更新。

But if you don't want to do that, you could also just make the variables public or protected in GlobalState and access them directly. And, you can make a static singleton as the Application object JavaDoc indicates:

但如果你不想这样做,你也可以将变量设置为公共的或受保护的,直接访问它们。并且,您可以创建一个静态的单例对象,如应用程序对象JavaDoc所示:

There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton.

通常不需要子类化应用程序。在大多数情况下,静态单例可以以更模块化的方式提供相同的功能。如果您的单例需要一个全局上下文(例如注册广播接收器),那么在第一次构造单例时,可以给检索它的函数一个上下文,这个上下文在内部使用context . getapplicationcontext()。

Using Intent data, as other answers here note is another way to pass data, but it's usually used for smaller data and simple types. You can pass larger/more complex data, but it's more involved than just using a static singleon. The Application object is still my personal favorite for sharing larger/more complex non persistent data between Android application components though (because it has a well defined lifecycle in an Android app).

使用意图数据(这里的其他答案)是传递数据的另一种方式,但它通常用于较小的数据和简单的类型。您可以传递更大/更复杂的数据,但这比使用静态singleon要复杂得多。应用程序对象仍然是我个人最喜欢在Android应用程序组件之间共享更大/更复杂的非持久性数据的对象(因为它在Android应用程序中有一个定义良好的生命周期)。

Also, as others have noted, if the data gets very complex and needs to be persistent then you can use SQLite or the filesystem too.

另外,正如其他人所指出的,如果数据变得非常复杂并且需要持久,那么您也可以使用SQLite或文件系统。

#5


7  

You could extend the Application class and tag on any objects you want there, they are then available anywhere in your application

您可以在任何需要的对象上扩展应用程序类和标记,然后在应用程序的任何地方都可以使用它们

#6


2  

Using the hashmap of weak reference approach, described above, and in http://developer.android.com/guide/faq/framework.html seems problematic to me. How are entire entries reclaimed, not just the map value? What scope do you allocate it in? As the framework is in control of the Activity lifecycle, having one of the participating Activities own it risks runtime errors when the owner is destroyed in advance of its clients. If the Application owns it, some Activity must explicitly remove the entry to avoid the hashmap from holding on to entries with a valid key and a potentially garbaged collected weak reference. Furthermore, what should a client do when the value returned for a key is null?

使用上面描述的弱引用方法的hashmap,以及http://developer.android.com/guide/faq/framework.html,对我来说似乎是有问题的。如何回收整个条目,而不仅仅是映射值?你在什么范围内分配它?由于框架控制活动生命周期,当所有者在其客户端之前被破坏时,让一个参与的活动拥有它的运行时错误风险。如果应用程序拥有该条目,那么某些活动必须显式地删除条目,以避免hashmap持有具有有效键和可能被加错的弱引用的条目。此外,当为键返回的值为空时,客户端应该做什么?

It seems to me that a WeakHashMap owned by the Application or within a singleton is a better choice. An value in the map is accessed via a key object, and when no strong references to the key exist (i.e. all Activities are done with the key and what it maps to), GC can reclaim the map entry.

在我看来,应用程序或单例模式拥有的弱hashmap是更好的选择。通过键对象访问映射中的值,并且当不存在对键的强引用时(也就是说,所有的活动都使用键和它映射到的内容),GC可以回收映射条目。

#7


1  

Well I have a few ideas, but I don't know if they are what your looking for.

我有一些想法,但我不知道它们是不是你想要的。

You could use a service that holds all of the data and then just bind your activities to the service for data retrival.

您可以使用一个保存所有数据的服务,然后将您的活动绑定到服务以进行数据检索。

Or package your data into a serializable or parcelable and attach them to a bundle and pass the bundle between activities.

或者将数据打包成可序列化或可分割的,并将它们附加到一个包中,并在活动之间传递该包。

This one may not be at all what your looking for, but you could also try using a SharedPreferences or a preference in general.

这个选项可能完全不是您想要的,但是您也可以尝试使用共享的首选项或一般的首选项。

Either way let me know what you decide.

不管怎样,让我知道你的决定。

#8


1  

Assuming you are calling activity two from activity one using an Intent.
You can pass the data with the intent.putExtra(),

假设您从活动一调用活动2,使用意图。您可以使用intent.putExtra()传递数据,

Take this for your reference. Sending arrays with Intent.putExtra

拿这个作为你的参考。发送数组与Intent.putExtra

Hope that's what you want.

希望这就是你想要的。

#9


1  

If your intention is to call other Activities from the current Activity, you should use Intents. Your focus could be less on persisting data than on sharing it on an as-needed basis.

如果您的意图是从当前活动调用其他活动,您应该使用意图。您的重点可能不是持久化数据,而是根据需要共享数据。

However, if you really need to persist these values then you could persist them in some kind of structured text file or database on local storage. A properties file, XML file, or JSON file could store your data and be easily parsed during activity creation. Don't forget also that you have SQLite on all Android devices, so you could store them in a database table. You could also use a Map to store key-value pairs and serialize the map to local storage, but this might be too cumbersome to be useful for simple data structures.

但是,如果您确实需要持久化这些值,那么您可以将它们保存在本地存储上的某种结构化文本文件或数据库中。属性文件、XML文件或JSON文件可以存储您的数据,并且在创建活动时很容易解析。不要忘记,在所有Android设备上都有SQLite,因此可以将它们存储在数据库表中。您还可以使用映射来存储键-值对并将映射序列化到本地存储,但是这对于简单的数据结构来说可能太麻烦了。

#10


1  

All of the aforementioned answers are great... I'm just adding one no one had mentioned yet about persisting data through activities and that is to use the built in android SQLite database to persist relevant data... In fact you can place your databaseHelper in the application state and call it as needed throughout the activates.. Or just make a helper class and make the DB calls when needed... Just adding another layer for you to consider... But all of the other answers would suffice as well.. Really just preference

以上的答案都很棒……我只是添加了一个还没有人提到过的通过活动来保存数据的方法,那就是使用android SQLite数据库来保存相关数据……实际上,您可以将databaseHelper设置为应用程序状态,并在整个激活过程中根据需要调用它。或者只是创建一个helper类,在需要的时候进行DB调用……只要再加一层给你考虑……但是所有其他的答案也足够了。只是偏好

#11


1  

Sharing data between activites example passing an email after login

在activites示例之间共享数据,在登录后传递电子邮件

"email" is the name that can be used to reference the value on the activity that's being requested

“email”是可以用来引用被请求活动的值的名称

1 Code on the login page

1登录页面上的代码

Intent openLoginActivity = new Intent(getBaseContext(), Home.class);
    openLoginActivity.putExtra("email", getEmail);

2 code on the home page

主页上的2个代码

Bundle extras = getIntent().getExtras();
    accountEmail = extras.getString("email");

#12


1  

There are various way to share data between activities

活动之间有各种共享数据的方法

1: Passing data between activities using Intent

1:使用意图在活动之间传递数据

Intent intent=new Intent(this, desirableActivity.class);
intent.putExtra("KEY", "Value");
startActivity(intent)

2: Using static keyword , define variable as public static and use any where in project

2:使用static关键字,将变量定义为public static,并在项目中的任何地方使用

      public static int sInitialValue=0;

use anywhere in project using classname.variableName;

在项目的任何地方使用类名。

3: Using Database

3:使用数据库

but its bit lengthy process, you have to use query for inserting data and iterate data using cursor when need. But there are no chance of losing data without cleaning cache.

但是它的冗长过程,您必须使用查询来插入数据并在需要时使用游标迭代数据。但是,如果不清理缓存,就不可能丢失数据。

4: Using shared Preferences

4:使用共享的偏好

much easier than database. but there is some limitation you can not save ArrayList ,List and custome objects.

更容易比数据库。但是存在一些限制,您不能保存ArrayList、List和custome对象。

5: Create getter setter in Aplication class and access any where in project.

5:在Aplication类中创建getter setter,并访问项目中的任何位置。

      private String data;
      public String getData() {
          return data;
      }

      public void setData(String data) {
          this.data = data;
      }

here set and get from activities

这里设置并从活动中获取

         ((YourApplicationClass)getApplicationContext()).setData("abc"); 

         String data=((YourApplicationClass)getApplicationContext()).getData();  

#13


0  

And if you wanna work with data object, this two implements very important:

如果你想处理数据对象,这两个实现非常重要:

Serializable vs Parcelable

  • Serializable is a marker interface, which implies the user cannot marshal the data according to their requirements. So when object implements Serializable Java will automatically serialize it.
  • Serializable(可串行化的)是一个标记接口,它意味着用户不能根据需求对数据进行编组。因此,当对象实现Serializable Java将自动序列化它。
  • Parcelable is android own serialization protocol. In Parcelable, developers write custom code for marshaling and unmarshaling. So it creates less garbage objects in comparison to Serialization
  • Parcelable是android自己的序列化协议。在Parcelable中,开发人员编写用于封送和反封送的自定义代码。因此,与序列化相比,它创建的垃圾对象更少
  • The performance of Parcelable is very high when comparing to Serializable because of its custom implementation It is highly recommended to use Parcelable implantation when serializing objects in android.
  • 由于Parcelable的自定义实现,与Serializable相比,它的性能非常高,因此强烈建议在android中序列化对象时使用Parcelable嵌入。

public class User implements Parcelable

公共类用户实现可共享

check more in here

检查更多的在这里