Android:在活动之间传递哈希映射

时间:2011-04-06 13:13:12

标签: android map android-activity android-intent

我在字符串和类对象之间有一个映射。我在Activity1中填充此地图,我想将其传递给activity2。

public class NEW extends Activity {

    public class data {
            String name;
            float value;
                 ....   etc  }

 ......   
    static Map<String, data> data_map = new HashMap<String, data>();
   .....  }

5 个答案:

答案 0 :(得分:53)

执行此操作的最佳方法是,如果您可以在Bundle支持的基元中表达您的数据,那么它可以放在您通过Intent.putExtra()方法发送的Intent中。 (除了使用Serializable,这是非常缓慢和低效的。)

但是你不能这样做是因为(a)你正在使用Map和(b)你的地图包含一个自定义数据类型。

这个确切问题的正式正确解决方案是编写一个自定义Parcellable类,负责编组/解组数据结构。我会在这里勾画出代码,虽然它可能不完全正确:

import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable.Creator;

public class MyData implements Parcelable {
    HashMap<String, data> data_map = new HashMap<String, data>();

    public MyData() {
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel dest, int parcelableFlags) {
        final int N = data_map.size();
        dest.writeInt(N);
        if (N > 0) {
            for (Map.Entry<String, data> entry : data_map.entrySet()) {
                dest.writeString(entry.getKey());
                data dat = entry.getValue();
                dest.writeString(dat.name);
                dest.writeFloat(dat.value);
                // etc...
            }
        }
    }

    public static final Creator<MyData> CREATOR = new Creator<MyData>() {
        public MyData createFromParcel(Parcel source) {
            return new MyData(source);
        }
        public MyData[] newArray(int size) {
            return new MyData[size];
        }
    };

    private MyData(Parcel source) {
        final int N = source.readInt();
        for (int i=0; i<N; i++) {
            String key = source.readString();
            data dat = new data();
            dat.name = source.readString();
            dat.value = source.readFloat();
            // etc...
            data_map.put(key, dat);
        }
    }
}

请注意,当您拥有类似“数据”类的自定义数据结构时,也可以更简洁地制作Parcellable,因此它知道如何在Parcel中读取/写入其内容,此处的代码只需调用.writeToParcel(...)和.readFromParcel(...)方法,而不是知道其内容的细节。这样,当您向“数据”添加新字段时,您不会忘记更新此其他编组代码以了解它们。

答案 1 :(得分:22)

我假设您拥有这两项活动(称为A和B)。在这种情况下,只需将地图放在公共静态变量中,然后通过A.data_map从B访问它。

[更新]

对于所有的downvotes,请查看Android Application Framework FAQ部分“如何在单个应用程序中的活动/服务之间传递数据?”。我推荐的解决方案与......完全相同。

  

公共静态字段/方法

     

制作数据的另一种方法   可在活动/服务中访问   是使用公共静态字段和/或   方法。您可以访问这些静态   来自你的任何其他类的字段   应用。要共享一个对象,   创建对象的活动   设置静态字段以指向此   对象和任何其他活动   想要使用这个对象只是访问   这个静态领域。

是的,这个解决方案有一些警告,但由于OP提供的信息有限,我们不能假设这种方法不起作用。

答案 2 :(得分:5)

我建议使用Intents,它既适用于静态对象又适用于任意对象(只要它们实现Serializable)。为您的应用程序创建一个自定义Intent,然后将您的HashMap(不是Map,它不实现Serializable!)作为额外数据传递:

Intent act2 = new Intent(Activity2.SHOW_ME);
act2.putExtra("data", data_map);

然后在Activity2中,您可以致电getIntent()并通过Intent.getAction().equals(Activity2.SHOW_ME)检查您是否是调用您的活动的人。如果是这样,您可以通过

访问您的额外数据
Intent caller = getIntent();
if (caller.getAction().equals(Activity2.SHOW_ME)) {
   Map<String, NEW.data> data_map = (Map<String, NEW.data>)caller.getExtras().get("data");
}

希望我正确键入所有内容;)这假设您的Intent操作字符串在Activity2中存储为static final string SHOW_ME = "yourpackage.yourname";

如果您需要进一步说明,请添加评论。

答案 3 :(得分:0)

您可以按照本文档中的描述将数据封装在绑定服务中:

http://developer.android.com/guide/topics/fundamentals/bound-services.html

不要忘记将您的服务器添加到清单文件中。

此解决方案的优势在于可以将数据与UI分离,从而最终实现更易于维护的设计。

如果需要,您可以在服务的API中添加一个消息包装器,以允许从其他进程/应用程序调用它

答案 4 :(得分:-3)

创建一个新的java文件,它将是整个应用程序的全局文件。

<强>步骤1

public class GlobalClass extends android.app.Application 
{
 public static Map<String, NEW.data> data_map = new Map<String, NEW.data>();
}

<强>第二步

执行此操作后,在AndroidManifest.xml中注册此“GlobalClass”

<application
    android:name=".GlobalClass"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
</application>

<强>步骤3

现在您可以在应用程序的任何位置使用此地图。

@Override
protected void onCreate(Bundle icicle)
{
 GlobalClass global = (GlobalClass)getApplication();
 Map<String, NEW.data> my_map_data = global.data_map;
}

这些步骤对您有帮助......