ToJson UI Hanging

I have an ArrayList of objects that I save in SharedPreferences in my onPause method. When I try to serialize it in json, I get the following in the logs (these two statements repeat and overload 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 

I initialize the ArrayList to onCreate and then pass the objects to it when I finish Asynctask execution. Here is the problem method that causes the user interface to freeze:

  @Override protected void onPause() { super.onPause(); String json = mGson.toJson(mSelectedContactList); mSharedPreferences.edit().putString("contact_list", json).apply(); } 

I also tried the following and keep on freezing:

  JsonElement element = mGson.toJsonTree(mSelectedContactList, new TypeToken<ArrayList<ContactObject>>() { }.getType()); String jsonString = element.getAsJsonArray().getAsString(); 

I know that the problem is not with SharedPreferences. I suspect the toJson method cannot handle this process, but I cannot figure out what the problem is. Any help would be much appreciated.

* EDIT: Here is the class I'm using:

 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; ... } 
+6
source share
4 answers

I had a similar problem. I could almost guarantee that the problem is that GSON is having difficulty serializing your InboxSmsObject or OutboxSmsObject. The ContactObject class looks simple, but you should keep in mind that GSON will also have to serialize objects in ArrayMap.

The first thing you need to do is try to change one or both of these classes inside the ContactObject class to some simple class like String. I would bet that serialization works in this scenario.

Once you confirm that this is true, you can work on the solution. The solution I used was to create a simple class with the settings needed to build InboxSmsObject. For example, create a class called InboxSmsObjectSettings that has only the essential information needed to create an instance of the InboxSmsObject class (I would assume that this class only needs a few lines). Then create a type constructor

InboxSmsObject (InboxSmsObjectSettings settings)

so you can easily create an InboxSmsObject instance from the settings. I know this is not the best solution since you have to transcode some things, but it worked for me.

0
source

This can be a recursive problem.

Please check if you have recursive models, for example:

 public class ClassA { ClassB b; } public class ClassB { List<ClassA> aList; } 
0
source

One possible cause of the problem is ProGuard-to over token, probably when obfuscation is not suppressed. I also had a very similar problem, and a common scenario:

  • There was only a simple external class containing only the TypeToken class, so it is a token type registry so as not to instantiate tokens every time I need to deserialize. It is worth noting (but does not really affect the case), type markers were exposed as static end fields visible as packets.
  • A deserializer was created that referenced the registry. When the first deserialization is performed (thus referring to the tokens type registry class), the application user interface thread hangs until the device asks that the application is frozen asking it to stop it.

I did not immediately notice that the static field initializers were the cause of the freeze. After some debugging, I realized that some constructor in the abstract TypeToken class TypeToken causing a hang. This is why simple access to the static field caused the application to freeze. I can’t remember which constructor calls it, but I would say that GSON type markers can work in an infinite loop somewhere in their internal components if your parameterization of type tokens is erased during ProGuard-ing. Therefore, simply reconfiguring ProGuard fixes the problem:

 -keepattributes Signature 

Read more about ProGuard Attributes .

0
source

If you have a constructor for ContactObject, just delete it. After that, it should work fine.

0
source

Source: https://habr.com/ru/post/989459/


All Articles