我目前正在开发一个Android应用程序(我是开发Android应用程序的初学者),我正在实现一个非常简单的类,它能够处理一个位置(纬度、经度)和相应的地址(使用Geocoder )。我希望我的应用程序能够在两个活动之间传输我的类的一个实例,并获得结果,这样的结果也是该类的一个实例。
我编写了类的声明来实现Parcelable类,如下所示(我的类名是OnePlace):
public class OnePlace implements Parcelable {
private LatLng position;
private String address;
…
}我使用方法实现了"OnePlace“类,以便能够实现Parcelable,这是文档中推荐的:https://developer.android.com/reference/android/os/Parcelable
一切都很好,我能够将类的一个实例从一个活动转移到另一个活动,并得到另一个实例作为结果。
下面是代码片段,在其中我将类的实例添加为与意图一起发送的数据:
OnePlace item = new OnePlace(); // create an instance of the class with default values
Intent mapIntent = new Intent(adapterView.getContext(), MapsActivity.class);
mapIntent.putExtra("place", item); // add the item as extra data to the intent
startActivityForResult(mapIntent, 35);在被调用的活动(这里是MapsActivity)中,我能够重建类实例的精确副本。
不管怎样,这是可行的,我对此很满意。
现在,我想将类的实例存储在一个文件中,当我下次启动我的应用程序时(一种永久存储的方式)该文件将被读取。
为此,我在我的活动的finish()方法中使用了以下代码片段(就在离开我的应用程序之前):
FileOutputStream outStream = openFileOutput("myFile.tmp", Context.MODE_PRIVATE);
ObjectOutputStream objectStream = new ObjectOutputStream(outStream);
objectStream.writeObject(item);
objectStream.close();
outStream.close();如您所见,我使用一个ObjectOutputStream类和一个FileOutputStream类来写入文件。item对象是我的OnePlace类的一个实例。我希望将这个实例永久存储到一个文件中,以便下次能够得到它。
当我调用writeObject(…)时方法时,调用以异常“对象不可序列化”结束。在阅读了一些在线文档之后,我们明确表示,我想要“序列化”的类应该实现可序列化接口(这是强制性的!)。
因此,我更新了类的定义如下:
public class OnePlace implements Parcelable, Serializable {
private LatLng position;
private String address;
…我稍微修改了类的定义,以实现Parcelable和Serializable接口。我不知道这是否是实现我的需要的最好方法…
当我想调用intent.putExtra("key",item)时,我会得到一个错误。实际上,Java编译器抱怨说它不知道它应该实现哪个putExtra接口:具有Parcelable的接口还是具有可序列化接口的?它的反应似乎是合乎逻辑的,我认为如果我是一个人类编译器,我可能会问同样的问题。
那么,现在,我该如何解决这个问题呢?有人有主意吗?也许,我想实现两个目标的方式(将类实例转移到另一个活动并永久存储实例)不是最好的方法吗?你有什么建议吗?
我提前感谢你的回答。
查尔斯
发布于 2018-08-11 05:33:09
最后,我设法找到了一个我觉得方便的优雅的解决方案。我只是想贴出我是如何做到的,如果它对其他寻找序列化对象的人有任何兴趣的话。
在我的OnePlace类的声明中,我最后只实现了Parcelable接口,以便能够在两个活动之间传输该类的实例(我不再实现序列化接口)。
public class OnePlace implements Parcelable {
private LatLng position;
private String address;
…
};然后,我在类中添加了以下新方法:
public String toJSON() {
JSONObject jsonObj = new JSONObject();
try {
jsonObj.put("address", address);
jsonObj.put("latitude", position.latitude);
jsonObj.put("longitude", position.longitude);
return jsonObj.toString();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}该方法创建一个包含位置信息(地址、纬度和经度)的JSON对象,然后返回等效字符串(这将用于进一步导出位置信息)。
然后,在我的MainActivity.finish()方法中,构建一个字符串数组列表,每个字符串包含与OnePlace类实例关联的JSON对象的字符串表示形式。这样做之后,我就可以序列化我的ArrayList,然后它是可序列化的(Java编译器不会抱怨!)这给了我一个长字符串,我写在我的应用程序首选项。
以下是代码:
public void finish() {
ArrayList<String> listInstances = new ArrayList<String>();
for(OnePlace item: listOfPlaces) {
listInstances.add(item.toJSON());
}
try {
ObjectSerializer objSerializer = new ObjectSerializer();
String serializedStr = objSerializer.serialize(listInstances);
myPrefs.edit().putString("places", serializedStr).apply();
} catch (Exception e) {
e.printStackTrace();
}
}现在,在我的MainActivity.onCreate()方法中,我从app首选项读取字符串,并将它转换回OneClass实例,如下所示:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// This is an array list that will contain all OnePlace instances
listOfPlaces = new ArrayList<OnePlace>();
myPreferences = this.getSharedPreferences("…", MODE_PRIVATE);
// I read back the String containing the serialized ArrayList
String placesStr = myPreferences.getString("places");
// An array list that will contain the list of JSONObjects, one object representing one instance on the OnePlace class
ArrayList<String> jsonObjList;
// I create a new ObjectSerializer object
ObjectSerializer objSerializer = new ObjectSerializer();
// Then, I deserialize into a list of JSONObjects
try {
// The myList object contains a list of JSONObjects
jsonObjList = (ArrayList<String>)objSerializer.deserialize(placesStr);
// I loop through the list of JSONObjects
for(String str: jsonObjList) {
// I create a JSONObject with one single string
JSONObject myJson = new JSONObject(str);
// Then, I get the values back and I use them to create a OnePlace class instance
LatLng position = new LatLng(myJson.getDouble("latitude"), myJson.getDouble("longitude"));
OnePlace myPlace = new OnePlace(position, myJson.getString("address");
// And finally, I add that OnePlace instance into my list of places
listOfPlaces.add(myPlace);
}
} catch (Exception e) {
e.printStackTrace();
};所以,我在这里总结一下我是如何做手术的:
对于保存过程,我执行以下操作:
对于恢复过程,我做以下工作:
而且效果很好!
发布于 2018-08-11 06:02:53
我建议您在活动、片段之间传递数据时使用葛森序列化。这是非常简单和轻量级的库。例如你的应用程序;
Gson gson = new Gson();
OnePlace item = new OnePlace(); // create an instance of the class with default values
Intent mapIntent = new Intent(adapterView.getContext(), MapsActivity.class);
mapIntent.putExtra("place", gson.toJson(item)); // add the item as extra data to the intent
startActivityForResult(mapIntent, 35);在MapsActivity.class中
Gson gson = new Gson();
String jsonPlace = getIntent().getStringExtra("place");
Place passedItem = gson.fromJson(jsonPlace, Place.class);https://stackoverflow.com/questions/51675834
复制相似问题