我有一个对象的ArrayList,我在Activities onPause方法中保存到SharedPreferences。当我尝试将它序列化为json时,我在日志中得到以下内容(这两个语句重复并重载logcat):
06-20 20:33:31.620 26245-26252/com.example.app W/art﹕ Suspending all threads took: 21.556ms
06-20 20:33:31.620 26245-26260/com.example.app W/art﹕ Suspending all threads took: 5.901ms
06-20 20:33:31.650 26245-26260/com.example.app I/art﹕ Background partial concurrent mark sweep GC freed 210493(6MB) AllocSpace objects, 87(2MB) LOS objects, 25% free, 47MB/63MB, paused 16.970ms total 155.761ms
06-20 20:33:32.480 26245-26260/com.example.app I/art﹕ Background sticky concurrent mark sweep GC freed 346396(10MB) AllocSpace objects, 140(4MB) LOS objects, 14% free, 48MB/56MB, paused 13ms total 88.199ms
我在onCreate中初始化ArrayList,然后在执行Asynctask时给它提供对象。以下是导致UI冻结的问题方法:
@Override
protected void onPause() {
super.onPause();
String json = mGson.toJson(mSelectedContactList);
mSharedPreferences.edit().putString("contact_list", json).apply();
}
我也尝试了以下内容并继续冻结:
JsonElement element =
mGson.toJsonTree(mSelectedContactList, new TypeToken<ArrayList<ContactObject>>() {
}.getType());
String jsonString = element.getAsJsonArray().getAsString();
我知道问题不在于SharedPreferences。我怀疑toJson方法无法处理这个过程,但我无法弄清楚这里有什么问题。任何帮助都感激不尽。
*编辑:这是我正在使用的课程:
public class ContactObject implements Parcelable {
// Instance variables
private String mID;
private String mNumber;
private String mName;
private boolean mHasPhoto;
private ArrayMap<Long, InboxSmsObject> mSentMessages;
private ArrayMap<Long, OutboxSmsObject> mReceivedMessages;
...
}
答案 0 :(得分:0)
我遇到过类似的问题。我几乎可以保证问题是由于GSON很难序列化您的InboxSmsObject或OutboxSmsObject对象。您的ContactObject类看起来很简单,但您必须记住,GSON还必须序列化ArrayMap中的对象。
您应该做的第一件事是尝试将ContactObject类中的一个或两个类更改为一些简单的类,如String。我敢打赌,序列化在这种情况下有效。
一旦确认确实如此,那么您就可以开始使用解决方案了。我使用的解决方案是创建一个简单的类,只需要构造InboxSmsObject所需的设置。例如,创建一个名为InboxSmsObjectSettings的类,它只包含实例化InboxSmsObject类所需的基本信息(我猜这个类只需要几个字符串)。然后创建一个像
这样的构造函数InboxSmsObject(InboxSmsObjectSettings设置)
这样您就可以从设置中轻松实例化InboxSmsObject。我知道这不是最好的解决方案,因为你必须重新编码一些东西,但它对我有用。
答案 1 :(得分:0)
这可能是一个递归问题。
请检查您是否具有递归模型,例如:
public class ClassA {
ClassB b;
}
public class ClassB {
List<ClassA> aList;
}
答案 2 :(得分:0)
问题的一个可能原因是ProGuard-over over类型令牌,可能是在未抑制混淆时。我也有一个非常相似的问题,整体情况是:
TypeToken
个实例,因此是一个类型标记注册表,以便每次我需要反序列化时不实例化类型标记。值得注意的是(但并未真正影响案例),类型标记作为包可见的静态最终字段公开。我没有立即注意到静态字段初始化器是冻结的原因。经过一些调试后,我意识到抽象TypeToken
类中的一些构造函数会导致挂起。这就是为什么只是一个简单的访问静态字段导致应用程序冻结。我真的不记得哪个构造函数导致它,但我会声称如果在ProGuarding期间擦除了类型标记参数化,GSON类型标记可能会在其内部某处遇到无限循环。因此,重新配置ProGuard可以解决问题:
-keepattributes Signature
查看ProGuard Attributes的详情。
答案 3 :(得分:0)
如果你有ContactObject的构造函数,只需删除它。之后它应该可以正常工作。