android.os.TransactionTooLargeException 在 AsyncTask 中使用 Gson Writing/Reading JSON 时发生

android.os.TransactionTooLargeException occurs when Writing/Reading JSON with Gson in AsyncTask

在我的应用程序中,我将带有 GSON 的电子邮件保存到一个 .json 文件中。由于冻结 UI,我必须在后台执行此操作。我尝试使用 "new Thread" 但我遇到了 Gson 的解析错误,所以我现在正在尝试使用 AsyncTask...

我的 logcat 发布了这个:

03-12 14:36:34.750 30486-30504/at.guger.email I/art: Background sticky concurrent mark sweep GC freed 274498(12MB) AllocSpace objects, 0(0B) LOS objects, 27% free, 21MB/29MB, paused 5.096ms total 69.641ms 03-12 14:36:35.281 30486-30504/at.guger.email I/art: Background sticky concurrent mark sweep GC freed 170008(7MB) AllocSpace objects, 0(0B) LOS objects, 25% free, 21MB/29MB, paused 5.615ms total 54.870ms 03-12 14:36:35.741 30486-30504/at.guger.email I/art: Background sticky concurrent mark sweep GC freed 157620(6MB) AllocSpace objects, 0(0B) LOS objects, 24% free, 22MB/29MB, paused 5.676ms total 59.539ms 03-12 14:36:36.212 30486-30504/at.guger.email I/art: Background partial concurrent mark sweep GC freed 151786(6MB) AllocSpace objects, 0(0B) LOS objects, 40% free, 22MB/38MB, paused 9.185ms total 107.879ms 03-12

14:36:37.193 30486-30504/at.guger.email I/art: Background sticky concurrent mark sweep GC freed 355102(14MB) AllocSpace objects, 0(0B) LOS objects, 24% free, 24MB/32MB, paused 12.054ms total 130.218ms

03-12 14:36:37.753 30486-30504/at.guger.email I/art: Background sticky concurrent mark sweep GC freed 181500(6MB) AllocSpace objects, 97(1195KB) LOS objects, 23% free, 24MB/32MB, paused 8.087ms total 105.010ms

这可能重复了 100 次..

然后这个放出来:

03-12 14:37:02.858 30486-31452/at.guger.email E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #3 Process: at.guger.email, PID: 30486 java.lang.RuntimeException: An error occured while executing doInBackground() at android.os.AsyncTask.done(AsyncTask.java:304) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) at java.util.concurrent.FutureTask.setException(FutureTask.java:222) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:818) Caused by: java.lang.WhosebugError: stack size 1036KB at com.google.gson.internal.$Gson$Types.canonicalize($Gson$Types.java:111) at com.google.gson.internal.$Gson$Types$WildcardTypeImpl.($Gson$Types.java:553) at com.google.gson.internal.$Gson$Types.canonicalize($Gson$Types.java:111) at com.google.gson.internal.$Gson$Types$WildcardTypeImpl.($Gson$Types.java:546) at com.google.gson.internal.$Gson$Types.canonicalize($Gson$Types.java:111)

14:37:03.078 30486-30504/at.guger.email I/art: Background partial concurrent mark sweep GC freed 2071991(33MB) AllocSpace objects, 16(10MB) LOS objects, 30% free, 36MB/52MB, paused 2.105ms total 219.940ms 03-12 14:37:03.088 30486-31452/at.guger.email D/Error: ERR: exClass=java.lang.WhosebugError 03-12 14:37:03.088 30486-31452/at.guger.email D/Error: ERR: exMsg=stack size 1036KB 03-12 14:37:03.088 30486-31452/at.guger.email D/Error: ERR: file=$Gson$Types.java 03-12 14:37:03.088 30486-31452/at.guger.email D/Error: ERR: class=com.google.gson.internal.$Gson$Types 03-12 14:37:03.088 30486-31452/at.guger.email D/Error: ERR: method=canonicalize line=111 03-12 14:37:03.108 30486-30499/at.guger.email W/art: Suspending all threads took: 10.559ms 03-12 14:37:03.118 30486-31452/at.guger.email D/Error: ERR: stack=java.lang.RuntimeException: An error occured while executing doInBackground() at android.os.AsyncTask.done(AsyncTask.java:304) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) at java.util.concurrent.FutureTask.setException(FutureTask.java:222) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:818) Caused by: java.lang.WhosebugError: stack size 1036KB at com.google.gson.internal.$Gson$Types.canonicalize($Gson$Types.java:111) at com.google.gson.internal.$Gson$Types$WildcardTypeImpl.($Gson$Types.java:553)

30486-31452/at.guger.email D/Error: ERR: TOTAL BYTES WRITTEN: 2240396 03-12 14:37:03.118 30486-31452/at.guger.email E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! 03-12 14:37:03.118 30486-31452/at.guger.email E/AndroidRuntime: Error reporting crash android.os.TransactionTooLargeException at android.os.BinderProxy.transactNative(Native Method) at android.os.BinderProxy.transact(Binder.java:496) at android.app.ActivityManagerProxy.handleApplicationCrash(ActivityManagerNative.java:4200) at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:89) at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693) at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)

如果我尝试在 MainThread 上执行代码,我的代码就可以工作:

File dir = new File(mailParcel.getContext().getFilesDir() + "/emails/" + mailParcel.getDirectory() + "/" + foldername);

if (!dir.exists()) dir.mkdirs();

for (File f : dir.listFiles()) {
    f.delete();
}

String fileName;
File file;
Mail[] Mails = mailParcel.getMails();

for (int i = 0; i < Mails.length; i++) {
    fileName = Mails[i].getReceiveDate().toString().replace(" ", "_").replace(":", "-");

    try {
        file = new File(dir, fileName + ".json");

        file.createNewFile();

        Writer writer = new OutputStreamWriter(new FileOutputStream(file));

        Gson gson = new GsonBuilder().create();
        gson.toJson(Mails[i], writer);

        writer.close();
    }
    catch (FileNotFoundException fnfe) {
        fnfe.printStackTrace();
    }
    catch (UnsupportedEncodingException usee) {
        usee.printStackTrace();
    }
    catch (IOException ioe) {
        ioe.printStackTrace();
    }
}

希望你能帮帮我! 如果您有其他想法而不是例如在 Asynctask 中做,请告诉我!

答案真的很简单...

我创建了一个 AsyncTask 而不是线程。 然后代码工作。