Cara menangani: java.util.concurrent.TimeoutException: android.os.BinderProxy.finalize () kehabisan waktu setelah 10 detik kesalahan?

167

Kami melihat beberapa TimeoutExceptionsdi GcWatcher.finalize, BinderProxy.finalize, dan PlainSocketImpl.finalize. 90+% dari mereka terjadi di Android 4.3. Kami menerima laporan ini dari Crittercism dari pengguna di lapangan.

masukkan deskripsi gambar di sini

Kesalahan adalah variasi dari: " com.android.internal.BinderInternal$GcWatcher.finalize() timed out after 10 seconds"

java.util.concurrent.TimeoutException: android.os.BinderProxy.finalize() timed out after 10 seconds
at android.os.BinderProxy.destroy(Native Method)
at android.os.BinderProxy.finalize(Binder.java:459)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:187)
at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:170)
at java.lang.Thread.run(Thread.java:841)

Sejauh ini kami belum beruntung mereproduksi masalah di rumah atau mencari tahu apa yang menyebabkannya.

Adakah ide yang dapat menyebabkan ini? Adakah yang tahu cara men-debug ini dan mencari tahu bagian mana dari aplikasi yang menyebabkan ini? Apa pun yang menjelaskan masalah ini akan membantu.

Stacktraces lainnya:

1   android.os.BinderProxy.destroy  
2   android.os.BinderProxy.finalize Binder.java, line 482
3   java.lang.Daemons$FinalizerDaemon.doFinalize    Daemons.java, line 187
4   java.lang.Daemons$FinalizerDaemon.run   Daemons.java, line 170
5   java.lang.Thread.run    Thread.java, line 841  

2

1   java.lang.Object.wait   
2   java.lang.Object.wait   Object.java, line 401
3   java.lang.ref.ReferenceQueue.remove ReferenceQueue.java, line 102
4   java.lang.ref.ReferenceQueue.remove ReferenceQueue.java, line 73
5   java.lang.Daemons$FinalizerDaemon.run   Daemons.java, line 170
6   java.lang.Thread.run

3

1   java.util.HashMap.newKeyIterator    HashMap.java, line 907
2   java.util.HashMap$KeySet.iterator   HashMap.java, line 913
3   java.util.HashSet.iterator  HashSet.java, line 161
4   java.util.concurrent.ThreadPoolExecutor.interruptIdleWorkers    ThreadPoolExecutor.java, line 755
5   java.util.concurrent.ThreadPoolExecutor.interruptIdleWorkers    ThreadPoolExecutor.java, line 778
6   java.util.concurrent.ThreadPoolExecutor.shutdown    ThreadPoolExecutor.java, line 1357
7   java.util.concurrent.ThreadPoolExecutor.finalize    ThreadPoolExecutor.java, line 1443
8   java.lang.Daemons$FinalizerDaemon.doFinalize    Daemons.java, line 187
9   java.lang.Daemons$FinalizerDaemon.run   Daemons.java, line 170
10  java.lang.Thread.run

4

1   com.android.internal.os.BinderInternal$GcWatcher.finalize   BinderInternal.java, line 47
2   java.lang.Daemons$FinalizerDaemon.doFinalize    Daemons.java, line 187
3   java.lang.Daemons$FinalizerDaemon.run   Daemons.java, line 170
4   java.lang.Thread.run
emmby
sumber
2
Sudahlah, menemukannya bugzilla.mozilla.org/show_bug.cgi?id=864102 Saya juga dapat mengonfirmasi bahwa ini memengaruhi aplikasi kami, baunya seperti masalah Layanan Google Play
eveliotc
Baris kode di mana kesalahan dilemparkan diperkenalkan Versi 4.3_r1, yang dirilis pada 5 Juni 2013. Mungkin masalah terjadi sejak saat itu.
edubriguenti
Android versi 4.2.2 juga mulai membuang pengecualian ini jadi mungkin ini pembaruan google play yang merupakan sumbernya.
JWqvist
@EvelioTarazona Saya memilikinya di beberapa aplikasi yang tidak menggunakan layanan bermain
ligi
@ ligi apakah ini tumpukan jejak yang sama untuk Anda?
eveliotc

Jawaban:

220

Pengungkapan penuh - Saya penulis pembicaraan yang disebutkan sebelumnya dalam TLV DroidCon.

Saya memiliki kesempatan untuk memeriksa masalah ini di banyak aplikasi Android, dan mendiskusikannya dengan pengembang lain yang menjumpainya - dan kami semua mencapai titik yang sama: masalah ini tidak dapat dihindari, hanya diminimalkan.

Saya melihat lebih dekat pada implementasi default kode kolektor Android Garbage, untuk lebih memahami mengapa pengecualian ini dilemparkan dan tentang apa yang mungkin menjadi penyebabnya. Saya bahkan menemukan akar penyebab yang mungkin selama eksperimen.

Akar masalahnya adalah pada titik perangkat "Goes to Sleep" untuk sementara waktu - ini berarti bahwa OS telah memutuskan untuk menurunkan konsumsi baterai dengan menghentikan sebagian besar proses Pengguna Tanah untuk sementara waktu, dan mematikan Layar, mematikan siklus CPU , dll. Cara ini dilakukan - ada pada level sistem Linux di mana proses-proses dijeda pada pertengahan berjalan. Ini dapat terjadi kapan saja selama eksekusi Aplikasi normal, tetapi itu akan berhenti pada panggilan sistem Native, karena pengalihan konteks dilakukan pada level kernel. Jadi - di sinilah Dalvik GC bergabung dengan cerita ini.

Kode Dalvik GC (seperti yang diterapkan dalam proyek Dalvik di situs AOSP) bukan sepotong kode yang rumit. Cara dasar kerjanya dicakup dalam slide DroidCon saya. Yang tidak saya bahas adalah loop GC dasar - pada titik di mana kolektor memiliki daftar Objek untuk diselesaikan (dan dihancurkan). Logika loop di pangkalan dapat disederhanakan seperti ini:

  1. mengambil starting_timestamp ,
  2. hapus objek untuk daftar objek yang akan dirilis,
  3. melepaskan objek - finalize()dan panggilan aslidestroy() jika diperlukan,
  4. mengambil end_timestamp ,
  5. menghitung (end_timestamp - starting_timestamp ) dan membandingkannya dengan nilai batas waktu kode 10 detik,
  6. jika batas waktu telah tercapai - lempar java.util.concurrent.TimeoutExceptiondan matikan prosesnya.

Sekarang pertimbangkan skenario berikut:

Aplikasi berjalan bersama melakukan hal tersebut.

Ini bukan aplikasi yang menghadap pengguna, ini berjalan di latar belakang.

Selama operasi latar belakang ini, objek dibuat, digunakan dan perlu dikumpulkan untuk melepaskan memori.

Aplikasi tidak mengganggu dengan WakeLock - karena ini akan mempengaruhi baterai dengan buruk, dan sepertinya tidak perlu.

Ini berarti Aplikasi akan meminta GC dari waktu ke waktu.

Biasanya proses GC selesai tanpa hambatan.

Terkadang (sangat jarang) sistem akan memutuskan untuk tidur di tengah menjalankan GC.

Ini akan terjadi jika Anda menjalankan aplikasi Anda cukup lama, dan memonitor log memori Dalvik dengan cermat.

Sekarang - pertimbangkan logika cap waktu dari loop GC dasar - adalah mungkin bagi perangkat untuk memulai menjalankan, mengambil start_stamp, dan pergi tidur pada destroy()panggilan asli pada objek sistem.

Ketika bangun dan melanjutkan lari, destroy()akan selesai, dan berikutnya end_stampakan menjadi waktu yang dibutuhkan destroy()panggilan + waktu tidur.

Jika waktu tidur panjang (lebih dari 10 detik), java.util.concurrent.TimeoutExceptionakan terlempar.

Saya telah melihat ini dalam grafik yang dihasilkan dari skrip python analisis - untuk Aplikasi Sistem Android, bukan hanya aplikasi saya sendiri yang dipantau.

Kumpulkan log yang cukup dan pada akhirnya Anda akan melihatnya.

Intinya:

Masalahnya tidak dapat dihindari - Anda akan menjumpainya jika aplikasi Anda berjalan di latar belakang.

Anda dapat mengurangi dengan mengambil WakeLock, dan mencegah perangkat dari tidur, tapi itu adalah cerita yang berbeda sama sekali, dan sakit kepala baru, dan mungkin pembicaraan lain di penipu lain.

Anda dapat meminimalkan masalah dengan mengurangi panggilan GC - membuat skenario lebih kecil kemungkinannya (tips ada di slide).

Saya belum memiliki kesempatan untuk membahas kode Dalvik 2 (alias ART) GC - yang menawarkan fitur Generational Compacting baru, atau melakukan percobaan apa pun pada Android Lollipop.

Ditambahkan 7/5/2015:

Setelah meninjau agregasi laporan kerusakan untuk jenis kerusakan ini, sepertinya kerusakan ini dari versi 5.0+ dari OS Android (Lollipop dengan ART) hanya menyumbang 0,5% dari jenis kerusakan ini. Ini berarti bahwa perubahan ART GC telah mengurangi frekuensi gangguan ini.

Ditambahkan 6/1/2016:

Sepertinya proyek Android telah menambahkan banyak info tentang cara kerja GC di Dalvik 2.0 (alias ART).

Anda dapat membacanya di sini - Debugging ART Garbage Collection .

Itu juga membahas beberapa alat untuk mendapatkan informasi tentang perilaku GC untuk aplikasi Anda.

Mengirim SIGQUIT ke proses aplikasi Anda pada dasarnya akan menyebabkan ANR, dan membuang status aplikasi ke file log untuk dianalisis.

oba
sumber
Dalam kasus saya, saya juga berencana untuk mengurangi ini dengan mencari cara untuk mengurangi jumlah kode / waktu yang saya jalankan di latar belakang. Terima kasih atas riset Anda tentang topik ini.
parkerfath
menghapus pemrosesan latar belakang yang dilakukan di aplikasi Anda akan sangat membantu mengurangi masalah.
oba
Untuk apa nilainya, ini masih terjadi di Marshmallow (6.0.1). Yang mengatakan, saya hanya pernah menerima kesalahan ini satu kali. Jadi sepertinya itu bukan masalah besar. Terima kasih atas penjelasan lengkapnya.
Knossos
Setelah beberapa waktu, saya mendapat kesan berbeda bahwa memperbaiki masalah ini di OS sangat bermasalah, dan membutuhkan kerja sama antara Google dan OEM. Saya tidak berharap ini diperbaiki dalam waktu dekat.
oba
Saya menggunakan wakelock tetapi masih mengalami masalah ini di Android 4.4.2. Aplikasi saya memiliki beberapa operasi latar belakang tetapi terutama dirancang untuk bekerja sepanjang hari sambil mengisi kabel. Apakah ada cara lain untuk mengurangi masalah ini?
Orcun Sevsay
74

Kami melihat ini terus-menerus, di seluruh aplikasi kami, menggunakan Crashlytics. Kecelakaan biasanya terjadi pada kode platform. Sampel kecil:

android.database.CursorWindow.finalize () kehabisan waktu setelah 10 detik

java.util.regex.Matcher.finalize () kehabisan waktu setelah 10 detik

android.graphics.Bitmap $ BitmapFinalizer.finalize () kehabisan waktu setelah 10 detik

org.apache.http.impl.conn.SingleClientConnManager.finalize () kehabisan waktu setelah 10 detik

java.util.concurrent.ThreadPoolExecutor.finalize () kehabisan waktu setelah 10 detik

android.os.BinderProxy.finalize () kehabisan waktu setelah 10 detik

android.graphics.Path.finalize () kehabisan waktu setelah 10 detik

Perangkat tempat hal ini terjadi sebagian besar (tetapi tidak secara eksklusif) perangkat yang diproduksi oleh Samsung. Itu bisa berarti bahwa sebagian besar pengguna kami menggunakan perangkat Samsung; bergantian itu bisa menunjukkan masalah dengan perangkat Samsung. Saya tidak begitu yakin.

Saya kira ini tidak benar-benar menjawab pertanyaan Anda, tetapi saya hanya ingin menegaskan bahwa ini tampaknya cukup umum, dan tidak spesifik untuk aplikasi Anda.

Kevin Coppock
sumber
16
Ini terjadi untuk versi Android 5.0.1 juga dan sepertinya tidak terbatas pada perangkat Samsung. Itu terjadi pada Nexus 6.
Shobhit Puri
4
Saya memiliki masalah ini pada Android 4.4.4 dengan perangkat yang diproduksi oleh XIAOMI
Paresh Dudhat
Hanya ingin berpadu bahwa kita melihat sebagian besar crash di tablet samsung. Tidak yakin apa yang Samsung lakukan secara berbeda dengan cara tablet menangani aplikasi latar belakang.
FriendlyMikhail
1
Saya memiliki masalah ini di Android 4.4.4. perangkat yang diproduksi oleh HUAWEI.
Rameshbabu
1
Aplikasi saya mogok setelah jika saya menggunakan perpustakaan kenari bocor pada perangkat Android 5.0.2 Samsung. Jika saya menonaktifkan inisialisasi pustaka, aplikasi berfungsi dengan baik.
vanomart
15

Saya menemukan beberapa slide tentang masalah ini.

http://de.slideshare.net/DroidConTLV/android-crash-analysis-and-the-dalvik-garbage-collector-tools-and-tips

Dalam slide ini, penulis mengatakan bahwa sepertinya ada masalah dengan GC, jika ada banyak objek atau objek besar di tumpukan. Slide juga menyertakan referensi ke aplikasi sampel dan skrip python untuk menganalisis masalah ini.

https://github.com/oba2cat3/GCTest

https://github.com/oba2cat3/logcat2memorygraph

Selanjutnya saya menemukan petunjuk di komentar # 3 di sisi ini: https://code.google.com/p/android/issues/detail?id=53418#c3

Christopher
sumber
7

Kami memecahkan masalah dengan menghentikan FinalizerWatchdogDaemon.

public static void fix() {
    try {
        Class clazz = Class.forName("java.lang.Daemons$FinalizerWatchdogDaemon");

        Method method = clazz.getSuperclass().getDeclaredMethod("stop");
        method.setAccessible(true);

        Field field = clazz.getDeclaredField("INSTANCE");
        field.setAccessible(true);

        method.invoke(field.get(null));

    }
    catch (Throwable e) {
        e.printStackTrace();
    }
}

Anda dapat memanggil metode dalam siklus hidup Aplikasi, seperti attachBaseContext(). Untuk alasan yang sama, Anda juga dapat menentukan pembuatan ponsel untuk memperbaiki masalahnya, terserah Anda.

Enaoi
sumber
Tidak bekerja untuk kita, saya tidak mengerti mengapa. Kode selesai tanpa pengecualian tetapi kami masih menerima masalah itu dalam laporan Crashlytics dan Google Play Console.
Anton Breusov
5

Batas waktu Siaran Penerima setelah 10 detik. Mungkin Anda melakukan panggilan asinkron (salah) dari penerima siaran dan 4.3 benar-benar mendeteksinya.

danny117
sumber
3
Tampaknya tidak berguna untuk mendeteksinya dan tidak cukup memberi tahu Anda tentang hal itu. Memberitahu kami siaran mana yang bagus.
Aaron T Harris
Maaf jika saya salah, tapi saya tidak berpikir waktu tunggu penerima siaran menyebabkan kerusakan khusus ini. Ini praktik yang baik untuk menghindari batas 10-an, tapi itu masalah yang berbeda dari yang dimiliki pemohon.
parkerfath
Saya hanya punya 10 detik di otak. developer.android.com/training/articles/perf-anr.html IDK jika itu juga menyebabkan crash.
danny117
Maksud Anda solid dan praktik yang baik. Namun, poster asli memiliki pertanyaan spesifik tentang seperangkat perangkat tertentu. Saya akan menyarankan pemirsa lain dari pos ini untuk memeriksa jawaban Christopher dan jawaban oba jika mereka melihat gejala yang sama (perangkat Samsung (khususnya Galaxy S 4), dll.)
parkerfath
Saya di sini bukan untuk mem-bash perangkat memproduksi itu akan melanggar persyaratan.
danny117
5

Ini adalah solusi yang efektif dari didi untuk menyelesaikan masalah ini, Karena bug ini sangat umum dan sulit untuk menemukan penyebabnya, Kelihatannya lebih seperti masalah sistem, Mengapa kita tidak bisa mengabaikannya secara langsung? Tentu saja kita dapat mengabaikannya, Di sini adalah kode contoh:

final Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler = 
        Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread t, Throwable e) {
        if (t.getName().equals("FinalizerWatchdogDaemon") && e instanceof TimeoutException) {
        } else {
            defaultUncaughtExceptionHandler.uncaughtException(t, e);
        }
    }
});

Dengan menetapkan handler pengecualian uncaught default khusus, aplikasi dapat mengubah cara penanganan uncaught exception untuk utas yang sudah menerima perilaku default apa pun yang disediakan sistem. Ketika tidak tertangkap TimeoutExceptiondilemparkan dari utas bernamaFinalizerWatchdogDaemon , handler khusus ini akan memblokir rantai handler, handler sistem tidak akan dipanggil, jadi crash akan dihindari.

Melalui latihan, tidak ada efek buruk lain yang ditemukan. Sistem GC masih berfungsi, batas waktu dikurangi karena penggunaan CPU berkurang.

Untuk detail lebih lanjut lihat: https://mp.weixin.qq.com/s/uFcFYO2GtWWiblotem2bGg

Kiwi
sumber
4

Satu hal yang selalu benar adalah bahwa pada saat ini, perangkat akan mati lemas untuk beberapa memori (yang biasanya menjadi alasan GC kemungkinan besar dipicu).

Seperti yang disebutkan oleh hampir semua penulis sebelumnya, masalah ini muncul ketika Android mencoba menjalankan GC saat aplikasi di latar belakang. Dalam sebagian besar kasus di mana kami mengamatinya, pengguna menjeda aplikasi dengan mengunci layar mereka. Ini mungkin juga menunjukkan kebocoran memori di suatu tempat dalam aplikasi, atau perangkat sudah terlalu dimuat. Jadi satu-satunya cara yang sah untuk menguranginya adalah:

  • untuk memastikan tidak ada kebocoran memori, dan
  • untuk mengurangi jejak memori aplikasi secara umum.
Sankalp Sharma
sumber
1
try {
    Class<?> c = Class.forName("java.lang.Daemons");
    Field maxField = c.getDeclaredField("MAX_FINALIZE_NANOS");
    maxField.setAccessible(true);
    maxField.set(null, Long.MAX_VALUE);
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} catch (NoSuchFieldException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
}
kot32
sumber
Ini tidak akan menyelesaikan masalah jika durasi Tidur> 100 detik. Mengapa tidak mengaturnya menjadi MAX_INT?
oba
Ya, saya hanya melakukan contoh ~
kot32
1
Ini seharusnya tidak berfungsi karena inlining konstan. Mengubah nilai bidang tidak akan memengaruhi nilai yang dimasukkan ke penelepon.
hqzxzwb
0

FinalizeQueue mungkin terlalu panjang

saya pikir java mungkin memerlukan GC.SuppressFinalize () & GC.ReRegisterForFinalize () untuk memungkinkan pengguna mengurangi panjang finalizedQueue secara eksplisit

jika kode sumber JVM tersedia, dapat menerapkan metode ini sendiri, seperti pembuat ROM Android

Yessy
sumber
0

Sepertinya bug Android Runtime. Tampaknya ada finalizer yang berjalan di utasnya yang terpisah dan memanggil metode finalize () pada objek jika mereka tidak berada dalam bingkai stacktrace saat ini. Misalnya kode berikut (dibuat untuk memverifikasi masalah ini) berakhir dengan crash.

Mari kita memiliki beberapa kursor yang melakukan sesuatu dalam metode finalisasi (mis. SqlCipher, do close () yang mengunci ke database yang sedang digunakan)

private static class MyCur extends MatrixCursor {


    public MyCur(String[] columnNames) {
        super(columnNames);
    }

    @Override
    protected void finalize() {
        super.finalize();

        try {
            for (int i = 0; i < 1000; i++)
                Thread.sleep(30);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Dan kami melakukan beberapa hal yang berjalan lama setelah membuka kursor:

for (int i = 0; i < 7; i++) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                MyCur cur = null;
                try {
                    cur = new MyCur(new String[]{});
                    longRun();
                } finally {
                    cur.close();
                }
            }

            private void longRun() {
                try {
                    for (int i = 0; i < 1000; i++)
                        Thread.sleep(30);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

Ini menyebabkan kesalahan berikut:

FATAL EXCEPTION: FinalizerWatchdogDaemon
                                                                        Process: la.la.land, PID: 29206
                                                                        java.util.concurrent.TimeoutException: MyCur.finalize() timed out after 10 seconds
                                                                            at java.lang.Thread.sleep(Native Method)
                                                                            at java.lang.Thread.sleep(Thread.java:371)
                                                                            at java.lang.Thread.sleep(Thread.java:313)
                                                                            at MyCur.finalize(MessageList.java:1791)
                                                                            at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:222)
                                                                            at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:209)
                                                                            at java.lang.Thread.run(Thread.java:762)

Varian produksi dengan SqlCipher sangat mirip:

12-21 15:40:31.668: E/EH(32131): android.content.ContentResolver$CursorWrapperInner.finalize() timed out after 10 seconds
12-21 15:40:31.668: E/EH(32131): java.util.concurrent.TimeoutException: android.content.ContentResolver$CursorWrapperInner.finalize() timed out after 10 seconds
12-21 15:40:31.668: E/EH(32131): 	at java.lang.Object.wait(Native Method)
12-21 15:40:31.668: E/EH(32131): 	at java.lang.Thread.parkFor$(Thread.java:2128)
12-21 15:40:31.668: E/EH(32131): 	at sun.misc.Unsafe.park(Unsafe.java:325)
12-21 15:40:31.668: E/EH(32131): 	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:161)
12-21 15:40:31.668: E/EH(32131): 	at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:840)
12-21 15:40:31.668: E/EH(32131): 	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:873)
12-21 15:40:31.668: E/EH(32131): 	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1197)
12-21 15:40:31.668: E/EH(32131): 	at java.util.concurrent.locks.ReentrantLock$FairSync.lock(ReentrantLock.java:200)
12-21 15:40:31.668: E/EH(32131): 	at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)
12-21 15:40:31.668: E/EH(32131): 	at net.sqlcipher.database.SQLiteDatabase.lock(SourceFile:518)
12-21 15:40:31.668: E/EH(32131): 	at net.sqlcipher.database.SQLiteProgram.close(SourceFile:294)
12-21 15:40:31.668: E/EH(32131): 	at net.sqlcipher.database.SQLiteQuery.close(SourceFile:136)
12-21 15:40:31.668: E/EH(32131): 	at net.sqlcipher.database.SQLiteCursor.close(SourceFile:510)
12-21 15:40:31.668: E/EH(32131): 	at android.database.CursorWrapper.close(CursorWrapper.java:50)
12-21 15:40:31.668: E/EH(32131): 	at android.database.CursorWrapper.close(CursorWrapper.java:50)
12-21 15:40:31.668: E/EH(32131): 	at android.content.ContentResolver$CursorWrapperInner.close(ContentResolver.java:2746)
12-21 15:40:31.668: E/EH(32131): 	at android.content.ContentResolver$CursorWrapperInner.finalize(ContentResolver.java:2757)
12-21 15:40:31.668: E/EH(32131): 	at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:222)
12-21 15:40:31.668: E/EH(32131): 	at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:209)
12-21 15:40:31.668: E/EH(32131): 	at java.lang.Thread.run(Thread.java:762)

Lanjutkan: Tutup kursor ASAP. Setidaknya pada Samsung S8 dengan Android 7 di mana masalah telah terlihat.

vbevans94
sumber
0

Untuk kelas yang Anda buat (mis. Bukan bagian dari Android) dimungkinkan untuk menghindari crash sepenuhnya.

Setiap kelas yang mengimplementasikan finalize()memiliki beberapa kemungkinan crash yang tidak dapat dihindari seperti yang dijelaskan oleh @oba. Jadi, alih-alih menggunakan finalizer untuk melakukan pembersihan, gunakan aPhantomReferenceQueue .

Sebagai contoh, periksa penerapannya di React Native: https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/jni/DestructorThread.java

Ben
sumber