Menurut Google, saya harus " menonaktifkan panggilan ke metode Log dalam kode sumber " sebelum menerbitkan aplikasi Android saya ke Google Play. Ekstrak dari bagian 3 daftar periksa publikasi :
Pastikan Anda menonaktifkan logging dan menonaktifkan opsi debugging sebelum Anda membangun aplikasi Anda untuk rilis. Anda dapat menonaktifkan logging dengan menghapus panggilan ke metode Log dalam file sumber Anda.
Proyek open-source saya besar dan sulit melakukannya secara manual setiap kali saya merilis. Selain itu, menghapus baris Log berpotensi rumit, misalnya:
if(condition)
Log.d(LOG_TAG, "Something");
data.load();
data.show();
Jika saya mengomentari baris Log, maka ketentuannya berlaku untuk baris berikutnya, dan kemungkinan dimuat () tidak dipanggil. Apakah situasi seperti itu cukup langka sehingga saya dapat memutuskan bahwa seharusnya tidak ada?
Jadi, apakah ada cara tingkat kode sumber yang lebih baik untuk melakukan itu? Atau mungkin beberapa sintaks ProGuard pintar untuk menghapus semua baris Log secara efisien tapi aman?
sumber
sed 's_^\(\s*Log\.\)_;//'`date|tr -s \ -`'\1_g'
.Jawaban:
Saya menemukan solusi yang jauh lebih mudah adalah dengan melupakan semua
if
cek di semua tempat dan cukup gunakan ProGuard untuk menghapus panggilan metodeLog.d()
atau apa punLog.v()
ketika kita memanggilrelease
target Ant .Dengan begitu, kami selalu memiliki info debug yang menjadi keluaran untuk build reguler dan tidak harus membuat perubahan kode untuk build rilis. ProGuard juga dapat melakukan beberapa lintasan melewati kode byte untuk menghapus pernyataan yang tidak diinginkan lainnya, blok kosong dan secara otomatis dapat inline metode pendek jika diperlukan.
Sebagai contoh, berikut ini adalah konfigurasi ProGuard yang sangat mendasar untuk Android:
Jadi Anda akan menyimpannya di file, lalu panggil ProGuard dari Ant, dengan mengirimkan JAR yang baru dikompilasi dan platform Android JAR yang Anda gunakan.
Lihat juga contoh-contoh dalam manual ProGuard.
Pembaruan (4,5 tahun kemudian): Saat ini saya menggunakan Kayu untuk Android logging.
Tidak hanya itu sedikit lebih bagus daripada yang standar
Log
implementasi - tag log diatur secara otomatis, dan mudah untuk mencatat string dan pengecualian yang diformat - tetapi Anda juga dapat menentukan perilaku pencatatan yang berbeda saat runtime.Dalam contoh ini, pernyataan logging hanya akan ditulis ke logcat di build debug aplikasi saya:
Kayu diatur dalam
Application
onCreate()
metode saya :Kemudian di tempat lain dalam kode saya, saya bisa login dengan mudah:
Lihat contoh aplikasi Kayu untuk contoh lebih lanjut, di mana semua laporan log dikirim ke logcat selama pengembangan dan, dalam produksi, tidak ada laporan debug dicatat, tetapi kesalahan dilaporkan secara diam-diam ke Crashlytics.
sumber
Semua jawaban yang baik, tetapi ketika saya selesai dengan pengembangan saya, saya tidak ingin menggunakan apakah pernyataan di sekitar semua panggilan Log, juga tidak ingin menggunakan alat eksternal.
Jadi solusi yang saya gunakan adalah mengganti kelas android.util.Log dengan kelas Log saya sendiri:
Satu-satunya hal yang harus saya lakukan di semua file sumber adalah mengganti impor android.util.Log dengan kelas saya sendiri.
sumber
Log.d("tag", someValue.toString());
itu sangat mudah untuk lupa untuk memeriksa beberapa Nilai karena tidak nol apa artinya itu mungkin melemparNullPointerException
produksi. Ini menyarankan solusi yang aman tetapi itu akan menipu Anda. Kami, kamiprivate static boolean DEBUG
dan kemudianif(DEBUG)Log.d(TAG, msg);
String
. Solusi lengkap diuraikan di sini . Ini tampaknya memiliki kelemahan lain: setiap panggilan harus diedit (tidak hanya satu jalur impor).static final boolean LOG = BuildConfig.DEBUG
dan tidak harus memodifikasi file ini.Saya sarankan memiliki boolean statis di suatu tempat yang menunjukkan apakah akan masuk atau tidak:
Lalu di mana pun Anda ingin masuk kode Anda, lakukan saja ini:
Sekarang ketika Anda mengatur MyDebug.LOG ke false, kompiler akan menghapus semua kode di dalam pemeriksaan tersebut (karena ini adalah final statis, ia tahu pada waktu kompilasi kode itu tidak digunakan.)
Untuk proyek yang lebih besar, Anda mungkin ingin mulai memiliki boolean dalam file individual untuk dapat dengan mudah mengaktifkan atau menonaktifkan pencatatan yang diperlukan. Misalnya, ini adalah berbagai konstanta logging yang kita miliki di window manager:
Dengan kode yang sesuai seperti:
sumber
Solusi Christopher Proguard adalah yang terbaik, tetapi jika karena alasan apa pun Anda tidak menyukai Proguard, berikut adalah solusi yang sangat berteknologi rendah:
Log komentar:
Log tanda komentar:
Kendala adalah bahwa instruksi logging Anda tidak boleh menjangkau lebih dari beberapa baris.
(Jalankan baris ini dalam shell UNIX di root proyek Anda. Jika menggunakan Windows, dapatkan layer UNIX atau gunakan perintah Windows yang setara)
sumber
//
vs.;//
)Saya ingin menambahkan beberapa prasyarat tentang penggunaan Proguard dengan Android Studio dan gradle, karena saya punya banyak masalah untuk menghapus baris log dari biner terakhir.
Untuk membuat
assumenosideeffects
karya Proguard, ada prasyarat.Di file gradle Anda, Anda harus menentukan penggunaan
proguard-android-optimize.txt
file sebagai default.Sebenarnya, dalam
proguard-android.txt
file default , optimisasi dinonaktifkan dengan dua flag:The
proguard-android-optimize.txt
file tidak menambahkan garis, jadi sekarangassumenosideeffects
bisa bekerja.Kemudian, secara pribadi, saya menggunakan SLF4J , ketika saya mengembangkan beberapa perpustakaan yang didistribusikan kepada orang lain. Keuntungannya adalah secara default tidak ada output. Dan jika integrator menginginkan beberapa output log, ia dapat menggunakan Logback untuk Android dan mengaktifkan log, sehingga log dapat dialihkan ke file atau ke LogCat.
Jika saya benar-benar perlu menghapus log dari perpustakaan terakhir, saya kemudian menambahkan ke file Proguard saya (setelah mengaktifkan
proguard-android-optimize.txt
file tentu saja):sumber
proguard-android-optimize.txt
sebagai file Proguard default dan-assumenosideeffects
dalam file Proguard kustom diperlukan! Saya menggunakan shinker R8 (default saat ini) dan default Android logging.Saya sangat menyarankan menggunakan Kayu dari Jake Wharton
https://github.com/JakeWharton/timber
itu memecahkan masalah Anda dengan mengaktifkan / menonaktifkan ditambah menambahkan kelas tag secara otomatis
hanya
log hanya akan digunakan di versi debug Anda, dan kemudian gunakan
atau
untuk mencetak
"Kelas Anda / msg" tanpa menentukan tag
sumber
Saya telah menggunakan kelas LogUtils seperti pada aplikasi contoh Google IO. Saya memodifikasi ini untuk menggunakan aplikasi DEBUG konstan tertentu, bukan BuildConfig.DEBUG karena BuildConfig.DEBUG tidak dapat diandalkan . Kemudian di Kelas saya, saya memiliki yang berikut ini.
sumber
Build.DEBUG
yang biasa saya gunakan. Saya juga menyerah dengan berbagai solusi "benar" dan menggunakan solusi gaya yang mirip dengan Anda.Saya akan mempertimbangkan menggunakan fasilitas logging roboguice alih-alih android.util.Log bawaan
Fasilitas mereka secara otomatis menonaktifkan debug dan verbose log untuk rilis rilis. Plus, Anda mendapatkan beberapa fitur bagus secara gratis (misalnya perilaku logging yang dapat disesuaikan, data tambahan untuk setiap log, dan lainnya)
Menggunakan proguard bisa sangat merepotkan dan saya tidak akan mengalami kesulitan mengkonfigurasi dan membuatnya berfungsi dengan aplikasi Anda kecuali Anda memiliki alasan yang bagus untuk itu (menonaktifkan log bukan yang baik)
sumber
Saya memposting solusi ini yang berlaku khusus untuk pengguna Android Studio. Saya juga baru-baru ini menemukan Timber dan berhasil mengimpornya ke aplikasi saya dengan melakukan hal berikut:
Masukkan versi terbaru perpustakaan ke build.gradle Anda:
Kemudian di Android Studios, buka Edit -> Find -> Replace in Path ...
Ketik
Log.e(TAG,
atau bagaimanapun Anda telah menetapkan pesan Log ke dalam"Text to find"
kotak teks. Maka Anda tinggal menggantinya denganTimber.e(
Klik Temukan dan ganti semua.
Android Studios sekarang akan memeriksa semua file Anda di proyek Anda dan mengganti semua Log dengan Timbers.
Satu-satunya masalah yang saya miliki dengan metode ini adalah gradle muncul dengan sejuta pesan kesalahan setelah itu karena tidak dapat menemukan "Kayu" dalam impor untuk setiap file java Anda. Cukup klik pada kesalahan dan Android Studios akan secara otomatis mengimpor "Kayu" ke java Anda. Setelah Anda selesai melakukannya untuk semua file kesalahan, gradle akan dikompilasi lagi.
Anda juga perlu memasukkan kode ini ke
onCreate
metodeApplication
kelas Anda :Ini akan menghasilkan pendataan aplikasi hanya ketika Anda berada dalam mode pengembangan tidak dalam produksi. Anda juga dapat memiliki
BuildConfig.RELEASE
untuk masuk dalam mode rilis.sumber
import android\.util\.Log\;
Ganti dengan:import android\.util\.Log\;\nimport timber\.log\.Timber\;
Per android.util.Log menyediakan cara untuk mengaktifkan / menonaktifkan log:
Default metode ini adalahLoggable (...) mengembalikan false, hanya setelah Anda setprop di perangkat suka ini:
Ini berarti setiap log di atas level DEBUG dapat dicetak. Referensi dokumen android:
Jadi kita bisa menggunakan util log kustom:
sumber
Jika Anda dapat menjalankan penggantian global (sekali), dan setelah itu mempertahankan beberapa konvensi pengkodean, Anda dapat mengikuti pola yang sering digunakan dalam kerangka kerja Android .
Alih-alih menulis
memilikinya sebagai
Sekarang proguard dapat menghapus StringBuilder dan semua string dan metode yang digunakannya, dari rilis DEX yang dioptimalkan. Gunakan
proguard-android-optimize.txt
dan Anda tidak perlu khawatir tentang android.util.Log diproguard-rules.pro
:Dengan plugin Android Studio gradle, cukup dapat diandalkan, sehingga Anda tidak perlu konstanta tambahan untuk mengontrol stripping.
BuildConfig.DEBUG
sumber
Tambahkan berikut ini ke file proguard-rules.txt Anda
sumber
Ini adalah apa yang saya lakukan pada proyek android saya ..
Di Android Studio kita dapat melakukan operasi serupa dengan, Ctrl + Shift + F untuk mencari dari seluruh proyek (Command + Shift + F di MacOs) dan Ctrl + Shift + R untuk Ganti ((Command + Shift + R di MacOs))
sumber
Saya punya solusi yang sangat sederhana. Saya menggunakan IntelliJ untuk pengembangan, jadi detailnya berbeda-beda, tetapi idenya harus berlaku di semua IDE.
Saya memilih untuk me-root pohon sumber saya, klik kanan dan pilih untuk melakukan "ganti". Saya kemudian memilih untuk mengganti semua "Log." dengan "// Log.". Ini menghapus semua pernyataan log. Untuk mengembalikannya nanti saya ulangi penggantian yang sama tetapi kali ini ganti semua "// Log." dengan "Log.".
Bekerja sangat bagus untuk saya. Hanya ingat untuk mengatur penggantian sebagai case sensitif untuk menghindari kecelakaan seperti "Dialog." Untuk jaminan tambahan, Anda juga dapat melakukan langkah pertama dengan "Log." sebagai string untuk mencari.
Cemerlang.
sumber
Seperti yang disarankan komentar zserge ,
perpustakaan log-nya menyediakan sakelar aktifkan / nonaktifkan pencetakan log sederhana seperti di bawah ini.
Selain itu, hanya perlu mengubah
import
baris, dan tidak perlu mengubahLog.d(...);
pernyataan.sumber
Saya telah meningkatkan solusi di atas dengan memberikan dukungan untuk level log yang berbeda dan dengan mengubah level log secara otomatis tergantung pada apakah kode tersebut dijalankan pada perangkat langsung atau pada emulator.
sumber
ProGuard akan melakukannya untuk Anda pada rilis rilis Anda dan sekarang kabar baik dari android.com:
http://developer.android.com/tools/help/proguard.html
Alat ProGuard menyusut, mengoptimalkan, dan mengaburkan kode Anda dengan menghapus kode yang tidak digunakan dan mengganti nama kelas, bidang, dan metode dengan nama yang secara semantik tidak jelas. Hasilnya adalah file .apk berukuran lebih kecil yang lebih sulit untuk dibalik. Karena ProGuard membuat aplikasi Anda lebih sulit untuk direkayasa ulang, penting bagi Anda untuk menggunakannya saat aplikasi Anda menggunakan fitur yang sensitif terhadap keamanan seperti ketika Anda Melisensikan Aplikasi Anda.
ProGuard terintegrasi ke dalam sistem build Android, jadi Anda tidak perlu memintanya secara manual. ProGuard hanya berjalan ketika Anda membangun aplikasi dalam mode rilis, jadi Anda tidak harus berurusan dengan kode yang dikaburkan ketika Anda membangun aplikasi dalam mode debug. Menjalankan ProGuard sepenuhnya opsional, tetapi sangat disarankan.
Dokumen ini menjelaskan cara mengaktifkan dan mengkonfigurasi ProGuard serta menggunakan alat retrace untuk memecahkan kode jejak tumpukan yang dikaburkan
sumber
Saya suka menggunakan Log.d (TAG, beberapa string, seringkali sebuah String.format ()).
TAG selalu merupakan nama kelas
Transform Log.d (TAG, -> Logd (dalam teks kelas Anda
Dengan cara ini ketika Anda siap untuk membuat versi rilis, atur MainClass.debug ke false!
sumber
Log dapat dihapus menggunakan bash di linux dan sed:
Bekerja untuk log multiline. Dalam solusi ini Anda dapat yakin, bahwa log tidak ada dalam kode produksi.
sumber
Saya tahu ini adalah pertanyaan lama, tetapi mengapa Anda tidak mengganti semua panggilan log Anda dengan sesuatu seperti Boolean logCallWasHere = true; // --- sisa log Anda di sini
Ini sebabnya Anda akan tahu kapan Anda ingin mengembalikannya, dan mereka tidak akan memengaruhi panggilan pernyataan if Anda :)
sumber
Kenapa tidak lakukan saja
? Tidak diperlukan pustaka tambahan, tidak ada aturan proguard yang cenderung mengacaukan proyek dan kompiler java hanya akan meninggalkan bytecode untuk panggilan ini ketika Anda membuat rilis build.
sumber
Log.d("tag","msg");
, dan juga mudah untuk lupa menulisif(BuildConfig.DEBUG)
bagian itu.Ini solusi saya jika Anda tidak ingin mengacaukan dengan perpustakaan tambahan atau mengedit kode Anda secara manual. Saya membuat notebook Jupyter ini untuk membahas semua file java dan mengomentari semua pesan Log. Tidak sempurna tetapi itu menyelesaikan pekerjaan untuk saya.
sumber
jalanku:
1) aktifkan Mode Pemilihan Kolom (alt + shift + insert)
2) pilih satu Log.d (TAG, "text"); bagian 'Log.'
3) kemudian lakukan shift + ctrl + alt + j
4) klik panah kiri
5) lakukan shift + end
6) tekan delete.
ini menghapus semua panggilan LOG sekaligus dalam file java.
sumber
Anda dapat mencoba menggunakan metode konvensional sederhana ini:
Ctrl+ Shift+R
menggantikan
Dengan
sumber
Mudah dengan kotlin, cukup mendeklarasikan beberapa fungsi tingkat atas
sumber
cara paling sederhana;
menggunakan
DebugLog
Semua log dinonaktifkan oleh DebugLog ketika aplikasi dirilis.
https://github.com/MustafaFerhan/DebugLog
sumber