Android kilitlenme günlükleri nasıl alınır?


155

Pazar yerinde olmayan (hata ayıklama sertifikası ile imzalanmış) bir uygulamam var, ancak uygulamam çöktüğünde çökme günlüğü verisi almak istiyorum. Uygulamamın neden kilitlendiğini gösteren bir günlük nerede bulabilirim?

Yanıtlar:


139

Uygulamanız başka kişiler tarafından indiriliyorsa ve uzak cihazlarda kilitleniyorsa, bir Android hata raporlama kütüphanesine ( bu SO gönderisinde referansta bulunur) bakmak isteyebilirsiniz . Yalnızca kendi yerel aygıtınızdaysa, LogCat. çökme gerçekleştiğinde aygıt bir ana makineye bağlı olmasa bile, aygıtı bağlamak ve bir adb logcatkomut vermek tüm logcat geçmişini indirir (en azından genellikle günlük verilerinin bir döngüsü olan tamponludur, sadece sonsuz değildir). Bu seçeneklerden herhangi biri sorunuza cevap veriyor mu? Değilse, biraz daha aradığınızı netleştirmeye çalışabilir misiniz?


2
adb logcat komutunun nasıl kullanılacağını ayrıntılı olarak açıklayabilir misiniz? Bunu / SDK / tools dizininde çalıştırır mıyım? Dikkat etmem gereken bayraklar var mı? vb.
jesses.co.tt 18:13

2
@ jesses.co.tt Evet, sadece adb logcathangi adb bulunan herhangi bir dizinden çalıştırın . Alternatif olarak Eclipse eklentisi
Chris Thompson

2
Crashlytics, şimdiye kadar kullandığım en iyi uzaktan istisna günlüğü yazılımıdır. Tüm uygulamalarımda çıkıyor, kontrol et.
Jacksonkr

adb.exe bulunur $SDK_DIR/platform-tools/. Hata göstermek için:.\adb.exe logcat -v time *:E
Harun

53

Bunu yapmanın yolu, Thread.UncaughtExceptionHandlerarayüzü uygulamak ve Thread.setDefaultUncaughtExceptionHandler()Faaliyetinizin başlangıcına iletmektir onCreate(). İşte uygulama sınıfı TopExceptionHandler.

public class TopExceptionHandler implements Thread.UncaughtExceptionHandler {
    private Thread.UncaughtExceptionHandler defaultUEH;
    private Activity app = null;

    public TopExceptionHandler(Activity app) {
        this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
        this.app = app;
    }

    public void uncaughtException(Thread t, Throwable e) {
        StackTraceElement[] arr = e.getStackTrace();
        String report = e.toString()+"\n\n";
        report += "--------- Stack trace ---------\n\n";
        for (int i=0; i<arr.length; i++) {
            report += "    "+arr[i].toString()+"\n";
        }
        report += "-------------------------------\n\n";

        // If the exception was thrown in a background thread inside
        // AsyncTask, then the actual exception can be found with getCause

        report += "--------- Cause ---------\n\n";
        Throwable cause = e.getCause();
        if(cause != null) {
            report += cause.toString() + "\n\n";
            arr = cause.getStackTrace();
            for (int i=0; i<arr.length; i++) {
                report += "    "+arr[i].toString()+"\n";
            }
        }
        report += "-------------------------------\n\n";

        try {
            FileOutputStream trace = app.openFileOutput("stack.trace", 
                                                        Context.MODE_PRIVATE);
            trace.write(report.getBytes());
            trace.close();
        } catch(IOException ioe) {
        // ...
        }

        defaultUEH.uncaughtException(t, e);
    }
}

Not Android çerçevesinin defaultUEH değerinin işlemesine izin verdik.

Faaliyetinizin üst kısmında yukarıdaki sınıfın bir örneğini kaydedin:

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

Thread.setDefaultUncaughtExceptionHandler(new TopExceptionHandler(this));
...

Bu işleyici izlemeyi bir dosyaya kaydeder. Bir ReaderScopedahaki sefere yeniden başlatıldığında, dosyayı algılar ve kullanıcıya geliştiriciye e-posta ile göndermek isteyip istemediğini sorar.

Yığın İzlemesini E-postayla Göndermek için, e-postada paketlemek üzere aşağıdaki kodu yürütün.

try {
    BufferedReader reader = new BufferedReader(
        new InputStreamReader(ReaderScopeActivity.this.openFileInput("stack.trace")));
    while((line = reader.readLine()) != null) {
        trace += line+"\n";
    }
} catch(FileNotFoundException fnfe) {
    // ...
} catch(IOException ioe) {
    // ...
}

Intent sendIntent = new Intent(Intent.ACTION_SEND);
String subject = "Error report";
String body = "Mail this to appdeveloper@gmail.com: " + "\n" + trace + "\n";

sendIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"readerscope@altcanvas.com"});
sendIntent.putExtra(Intent.EXTRA_TEXT, body);
sendIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
sendIntent.setType("message/rfc822");

ReaderScopeActivity.this.startActivity(Intent.createChooser(sendIntent, "Title:"));

ReaderScopeActivity.this.deleteFile("stack.trace");

Veya ACRA Hata Raporlama Sistemini de kullanabilirsiniz. ACRA.jar dosyasını proje kitaplarınıza dahil edin ve başlatıcı etkinlik sınıfı bildiriminizden önce aşağıdaki kod snippet'ini kullanın

@ReportsCrashes(formKey = "", mailTo = "abc@gmail.com;def@yahoo.com", mode = ReportingInteractionMode.SILENT) 

veya Bunu konsoldan deneyebilirsiniz: -

adb logcat -b crash 

DefaultUEH.uncaughtException (t, e) satırı olmayacak; yöntemi uncaughtException () sonsuza kadar çağırmak?
Mickael Bergeron Néron

@ MickaelBergeronNéron no - sadece aynı Throwable'ı üst düzey işleyiciye transfer edecektir.
formatBCE


36

Bunu konsoldan deneyebilirsiniz:

adb logcat --buffer=crash 

Bu seçenek hakkında daha fazla bilgi:

adb logcat --help

...

  -b <buffer>, --buffer=<buffer>         Request alternate ring buffer, 'main',
                  'system', 'radio', 'events', 'crash', 'default' or 'all'.
                  Multiple -b parameters or comma separated list of buffers are
                  allowed. Buffers interleaved. Default -b main,system,crash.

9

Eclipse kullanıyorsanız, hata ayıklama kullandığınızdan ve çalışmadığınızdan emin olun. Hata ayıklama perspektifinde olduğunuzdan emin olun (sağ üst) Günlüğün yazdırılması için 'Devam Et'e (F8) birkaç kez basmanız gerekebilir. Çökme günlüğü, tam ekran için alt tıklatma Logcat penceresinde olacaktır ve aşağı kaydırdığınızdan emin olun. Hatalar için kırmızı metin göreceksiniz, kilitlenme izi gibi bir şey olacak

09-04 21:35:15.228: ERROR/AndroidRuntime(778): Uncaught handler: thread main exiting due to uncaught exception
09-04 21:35:15.397: ERROR/AndroidRuntime(778): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dazlious.android.helloworld/com.dazlious.android.helloworld.main}: java.lang.ArrayIndexOutOfBoundsException
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2268) 
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2284)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at android.app.ActivityThread.access$1800(ActivityThread.java:112)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1692)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at android.os.Handler.dispatchMessage(Handler.java:99)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at android.os.Looper.loop(Looper.java:123)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at android.app.ActivityThread.main(ActivityThread.java:3948)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at java.lang.reflect.Method.invokeNative(Native Method)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at java.lang.reflect.Method.invoke(Method.java:521)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at dalvik.system.NativeStart.main(Native Method)
09-04 21:35:15.397: ERROR/AndroidRuntime(778): Caused by: java.lang.ArrayIndexOutOfBoundsException
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at com.example.android.helloworld.main.onCreate(main.java:13)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2231)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     ... 11 more

Bunun önemli kısımları

09-04 21:35:15.397: ERROR/AndroidRuntime(778): Caused by: java.lang.ArrayIndexOutOfBoundsException
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at com.example.android.helloworld.main.onCreate(main.java:13)

Bu bize onCrate yönteminde main.java satır 13 satır sınırları dışında bir dizi olduğunu söylüyor.


9

Apphance kullanabilirsiniz. Bu, herhangi bir mobil cihazda (Android, iOS şimdi - geliştirilmekte olan diğerleri) uzaktan hata ayıklamaya izin veren bir çapraz platform hizmetidir (şimdi esas olarak Android, iOS yolda başka platformlarla birlikte). Bu sadece bir kilitlenmeden çok daha fazlasıdır, aslında çok daha fazlasıdır: günlük tutma, test uzmanları tarafından sorunların bildirilmesi, kilitlenmeler. Entegrasyon yaklaşık 5 dakika sürer. Şu anda kapalı beta sürümüne erişim talep edebilirsiniz.

Feragatname: Ben Apphance'ın arkasındaki bir şirket olan Polidea'nın CTO'su ve ortak yaratıcısıyım.

Güncelleme: Apphance artık kapalı beta değil! Güncelleme 2: Apphance, http://applause.com teklifinin bir parçası olarak sunulmaktadır


2
Sadece apphance denedim ve beğendim. Dokümanlar apphance lib'i uygulamanıza entegre ederken önemli bir noktayı kaçırdı; Eclipse ADT'nin en son sürümüyle, bu SO cevabının açıkladığı libsgibi apphance.jar dosyasını dizine koymalısınız . Bu github taahhüdü , apphance'i kullanmak için WorldMap uygulamamda yapmam gereken değişiklikleri gösteriyor.
JohnnyLambada

@HohnnyLambada Yorumunuz için teşekkür ederiz. Bunu daha net hale getirmek için belgeleri güncelledik.
Piotr Duda

12
bu kadar fazla ok almamalı, çoğu geliştirme bütçesinden 10 kat daha fazladır (ayda 2.500 $!)
user26676

bu yorumun yapıldığı tarihte 404'tür.
DaveP

Doğru. Uzun zaman önce uTest tarafından dalmıştı ve daha sonra tüm tekliflerini (Aphhance'ın özelliği dahil) Alkış'a yeniden markaladı. Şimdi applause.com
Jarek Potiuk


4

Şunlar arasından Acra kullanabilirsiniz bu . Bu kütüphaneyi projelerinize dahil etmek ve yapılandırmak için kilitlenme raporlarını (e-postanıza veya gdoc'larınıza) alabilirsiniz. Kötü İngilizcem için özür dilerim.


4

Temel bir çökme raporlama aracı arıyorsanız crashlytics'i deneyin .

Daha gelişmiş bir raporlama aracı istiyorsanız, Checkout Gryphonet . Oluşan tüm kilitlenmeler, kilitlenmeye neden olan tam kod satırıyla birlikte, kullanıcının kilitlenmeden önce attığı adımları ve daha fazlasını gösteren otomatik işaretçileri günlüğe kaydeder.

İyi şanslar!



2

Bu kütüphaneyi tüm sorunlarınızı çözmek için oluşturdum. Crash Reporter, tüm çökmelerinizi yakalamak ve yerel olarak cihazda oturum açmak için kullanışlı bir araçtır

Sadece bu bağımlılığı ekleyin ve hazırsınız.

compile 'com.balsikandar.android:crashreporter:1.0.1'

Cihazdaki tüm çökmelerinizi yerel olarak bulun ve bunları uygun bir şekilde düzeltin. Çökmeler, izlenmesi kolay tarih ve saat biçimi kullanılarak kaydedilir. Ayrıca aşağıdaki yöntemi kullanarak Kayıtlı İstisnaları yakalamak için API sağlar.

CrashRepoter.logException(Exception e)

Bir cihazın Kilitlenme Günlüklerini almak için kullandığınız Java sınıfı nedir?
Xenolion

Thread.UncaughtExceptionHandler arabirimi, işlenmemiş tüm kilitlenmeleri yakalamak için kullanılır. İşte aynı github.com/MindorksOpenSource/CrashReporter/blob/master/… için uygulama .
Bali

Tamam bunu kontrol edeyim ...! Teşekkürler
Xenolion

2

İşte tüm günlükleri bir metin dosyasına dökmenize yardımcı olabilecek bir çözüm

adb logcat -d > logs.txt


0

Telefonunuz bilgisayara bağlıyken kilitlenme günlüğünü arıyorsanız, Eclipse'deki DDMS görünümünü kullanın ve hata ayıklama sırasında uygulamanız kilitlendiğinde rapor DDMS içindeki LogCat'ta tam oradadır.


0

1) Telefonu USB üzerinden takın (Geliştirici Hata Ayıklama seçenekleri etkin)

2) Terminal'i açın ve Android SDK'nıza gidin (Mac için):

cd ~/Library/Android/sdk/platform-tools

3) Sabit bir günlük akışı oluşturmak için bu dizinden (terminalinizde) Logcat (Mac için):

./adb logcat

4) Kilitlenme günlükleri oluşturmak için kilitlenen uygulamanızı açın

5) Terminali durdurmak için Ctrl + C ve kilitlenen uygulama ile ilişkili günlükleri arayın. Aşağıdaki gibi bir şey söyleyebilir:

AndroidRuntime: FATAL EXCEPTION: main


0

Bu POST temel alınarak , "TopExceptionHandler" yerine bu sınıfı kullanın

class TopExceptionHandler implements Thread.UncaughtExceptionHandler {
private Thread.UncaughtExceptionHandler defaultUEH;
private Activity app = null;
private String line;

public TopExceptionHandler(Activity app) {
    this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
    this.app = app;
}

public void uncaughtException(Thread t, Throwable e) {




    StackTraceElement[] arr = e.getStackTrace();
    String report = e.toString()+"\n\n";
    report += "--------- Stack trace ---------\n\n";
    for (int i=0; i<arr.length; i++) {
        report += "    "+arr[i].toString()+"\n";
    }
    report += "-------------------------------\n\n";

    // If the exception was thrown in a background thread inside
    // AsyncTask, then the actual exception can be found with getCause

    report += "--------- Cause ---------\n\n";
    Throwable cause = e.getCause();
    if(cause != null) {
        report += cause.toString() + "\n\n";
        arr = cause.getStackTrace();
        for (int i=0; i<arr.length; i++) {
            report += "    "+arr[i].toString()+"\n";
        }
    }
    report += "-------------------------------\n\n";

    try {
        FileOutputStream trace = app.openFileOutput("stack.trace",
                Context.MODE_PRIVATE);
        trace.write(report.getBytes());
        trace.close();



        Intent i = new Intent(Intent.ACTION_SEND);
        i.setType("message/rfc822");
        i.putExtra(Intent.EXTRA_EMAIL  , new String[]{"kevineyni@gmail.com"});
        i.putExtra(Intent.EXTRA_SUBJECT, "crash report azar");
        String body = "Mail this to kevineyni@gmail.com: " + "\n" + trace + "\n";
        i.putExtra(Intent.EXTRA_TEXT   , body);
        try {
            startActivity(Intent.createChooser(i, "Send mail..."));
        } catch (android.content.ActivityNotFoundException ex) {
           // Toast.makeText(MyActivity.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
        }






      //  ReaderScopeActivity.this.startActivity(Intent.createChooser(sendIntent, "Title:"));

        //ReaderScopeActivity.this.deleteFile("stack.trace");

    } catch(IOException ioe) {
        // ...
    }

    defaultUEH.uncaughtException(t, e);
}

private void startActivity(Intent chooser) {
}

}

.....

aynı java sınıf dosyasında (Etkinlik) .....

Public class MainActivity.....

.....

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Thread.setDefaultUncaughtExceptionHandler(new TopExceptionHandler(this));

.....


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.