วิธีรับบันทึกข้อผิดพลาดของ Android


155

ฉันมีแอพที่ไม่ได้อยู่ในตลาด (ลงนามด้วยใบรับรองการแก้ไขข้อบกพร่อง) แต่ต้องการรับข้อมูลบันทึกข้อผิดพลาดทุกครั้งที่แอปพลิเคชันของฉันขัดข้อง ฉันจะหาบันทึกเหตุใดแอพของฉันจึงขัดข้อง

คำตอบ:


139

หากคนอื่นกำลังดาวน์โหลดแอปของคุณและหยุดทำงานบนอุปกรณ์ระยะไกลคุณอาจต้องการเข้าไปในห้องสมุดรายงานข้อผิดพลาดของ Android (อ้างอิงในโพสต์ SO นี้ ) หากเป็นเพียงอุปกรณ์ของคุณเองคุณสามารถใช้LogCat. แม้ว่าอุปกรณ์จะไม่ได้เชื่อมต่อกับเครื่องโฮสต์เมื่อเกิดการขัดข้องการเชื่อมต่ออุปกรณ์และการออกadb logcatคำสั่งจะดาวน์โหลดประวัติ logcat ทั้งหมด (อย่างน้อยที่สุดเท่าที่มันจะเป็น ถูกบัฟเฟอร์ซึ่งโดยปกติแล้วจะเป็น loooot ของข้อมูลบันทึกมันไม่ใช่แค่อนันต์) ตัวเลือกเหล่านี้ตอบคำถามของคุณหรือไม่ หากคุณไม่สามารถพยายามชี้แจงสิ่งที่คุณกำลังมองหาอีกเล็กน้อย?


2
คุณสามารถดูรายละเอียดวิธีการใช้คำสั่ง adb logcat ได้หรือไม่ ฉันรันสิ่งนี้ในไดเรกทอรี / SDK / tools หรือไม่ มีธงอะไรบ้างที่ฉันควรทราบ? ฯลฯ
jesses.co.tt

2
@ jesses.co.tt ใช่แค่เรียกใช้adb logcatจากสิ่งที่ไดเรกทอรี adb ตั้งอยู่หรือคุณสามารถใช้เครื่องมือ SDK ที่รวมอยู่ในปลั๊กอิน Eclipse
Chris Thompson

2
Crashlytics เป็นซอฟต์แวร์บันทึกข้อยกเว้นระยะไกลที่ดีที่สุดที่ฉันเคยใช้ มันจะออกไปในแอพทั้งหมดของฉันตรวจสอบมัน
Jacksonkr

adb.exe $SDK_DIR/platform-tools/ตั้งอยู่ใน เพื่อแสดงข้อผิดพลาด:.\adb.exe logcat -v time *:E
Harun

53

วิธีการทำเช่นนี้คือการใช้Thread.UncaughtExceptionHandlerอินเทอร์เฟซและส่งต่อไปThread.setDefaultUncaughtExceptionHandler()ที่จุดเริ่มต้นของกิจกรรมของonCreate()คุณ 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);
    }
}

หมายเหตุเราปล่อยให้เฟรมเวิร์กของ Android เป็นค่าเริ่มต้นUEHเพื่อจัดการมัน

ที่ด้านบนของกิจกรรมของคุณให้ลงทะเบียนตัวอย่างของคลาสดังกล่าว:

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

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

ตัวจัดการนี้บันทึกการติดตามในไฟล์ เมื่อReaderScopeรีสตาร์ทในครั้งต่อไปมันจะตรวจจับไฟล์และแจ้งให้ผู้ใช้ทราบหากเขา / เธอต้องการส่งอีเมลถึงผู้พัฒนา

หากต้องการส่งอีเมล Stack Trace ให้เรียกใช้รหัสต่อไปนี้เพื่อบรรจุในอีเมล

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");

หรือคุณสามารถใช้ ACRA Error Reporting System เพียงรวม ACRA.jar ใน libs โครงการของคุณและใช้ข้อมูลโค้ดด้านล่างก่อนการประกาศคลาสกิจกรรมตัวเรียกใช้ของคุณ

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

หรือคุณสามารถลองจากคอนโซล: -

adb logcat -b crash 

จะไม่บรรทัดเริ่มต้นUEH.uncaughtException (t, e); เรียกวิธีการ uncaughtException () อนันต์?
Mickael Bergeron Néron

@ MickaelBergeronNéronไม่มี - มันจะเป็นเพียงแค่การถ่ายโอน Throwable เดียวกันในการจัดการระดับบนสุด
formatBCE


36

คุณสามารถลองสิ่งนี้ได้จากคอนโซล:

adb logcat --buffer=crash 

ข้อมูลเพิ่มเติมเกี่ยวกับตัวเลือกนี้:

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 ตรวจสอบให้แน่ใจว่าคุณใช้ดีบักและไม่ทำงาน ให้แน่ใจว่าคุณอยู่ในมุมมองของการแก้ปัญหา (ขวาบน) คุณอาจจะต้องกดปุ่ม 'Resume (F8) ไม่กี่ครั้งสำหรับการเข้าสู่ระบบเพื่อพิมพ์ บันทึกความผิดพลาดจะอยู่ในหน้าต่าง Logcat ที่ดับเบิลคลิก bottom- สำหรับแบบเต็มหน้าจอและให้แน่ใจว่าคุณเลื่อนไปด้านล่าง คุณจะเห็นข้อความสีแดงเพื่อหาข้อผิดพลาดการติดตามข้อผิดพลาดจะเป็นอย่างไร

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

ส่วนที่สำคัญสำหรับชิ้นนี้คือ

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)

ผู้ที่บอกเราว่ามันเป็นข้อยกเว้นที่ไม่มีขอบเขตในบรรทัดที่ 13 ของ main.java ในวิธี onCrate


9

คุณสามารถใช้ Apphance นี่คือบริการข้ามแพลตฟอร์ม (ตอนนี้ส่วนใหญ่เป็น Android, iOS กับแพลตฟอร์มอื่น ๆ ในทางของพวกเขา) ซึ่งช่วยให้การแก้ปัญหาจากระยะไกลอุปกรณ์มือถือใด ๆ (Android, iOS ตอนนี้ - คนอื่น ๆ ภายใต้การพัฒนา) มันเป็นมากกว่าแค่ล็อกการทำงานผิดพลาดอันที่จริงแล้วมันมีมากกว่า: การบันทึกการรายงานปัญหาโดยผู้ทดสอบ crashlogs มันต้องใช้เวลาประมาณ 5 นาทีเพื่อบูรณาการ ขณะนี้คุณสามารถขอการเข้าถึงเบต้าที่ปิดแล้วได้

ข้อจำกัดความรับผิดชอบ: ฉันเป็น CTO ของ Polidea ซึ่งเป็น บริษัท ที่อยู่เบื้องหลัง Apphance และผู้สร้างร่วม

อัปเดต: Apphance จะไม่ปิดเบต้าอีกต่อไป! อัปเดต 2: การแสดงพร้อมใช้งานเป็นส่วนหนึ่งของการเสนอhttp://applause.com


2
ฉันแค่ลอง apphance และชอบมัน เอกสารพลาดจุดสำคัญเมื่อรวม lib แอปเข้ากับแอปของคุณ กับรุ่นล่าสุดของ Eclipse ADT คุณต้องใส่ apphance.jar ในlibsไดเรกทอรีเป็นนี้คำตอบ SO อธิบาย GitHub นี้แสดงให้เห็นถึงการเปลี่ยนแปลงที่ฉันต้องการเพื่อทำกับแอพ WorldMap ของฉันเพื่อใช้งาน
JohnnyLambada

@HohnnyLambada ขอบคุณสำหรับความคิดเห็นของคุณ เราได้อัปเดตเอกสารเพื่อให้ชัดเจนยิ่งขึ้น
Piotr Duda

12
นี่ไม่ควรมีลูกศรมากนักมันมีค่าใช้จ่ายมากกว่างบประมาณการพัฒนามากถึง 10 เท่า ($ 2,500 ต่อเดือน!)
26676

apphance คือ 404 ณ วันที่ความคิดเห็นนี้
DaveP

แก้ไข. เมื่อนานมาแล้วโดย uTest ซึ่งได้ทำการเปลี่ยนโฉมการนำเสนอทั้งหมดของพวกเขา (รวมถึงฟีเจอร์ของ Aphhance) ไปยังเสียงปรบมือ ดังนั้นตอนนี้มันเป็นapplause.com
Jarek Potiuk

8

นี่เป็นอีกวิธีในการบันทึก Crash

ตลาด Android มีเครื่องมือชื่อ "Crash Collector"

ตรวจสอบลิงค์ต่อไปนี้สำหรับข้อมูลเพิ่มเติม

http://kpbird.blogspot.com/2011/08/android-application-crash-logs.html


3
ไม่ทำงานบน Android 4.1 และใหม่กว่า (สิทธิ์ใหม่ในการอ่านบันทึก)
แมว

4

คุณสามารถใช้ ACRA จากนี้ รวมทั้งห้องสมุดนี้ให้กับโครงการของคุณและตั้งค่าว่าคุณจะได้รับ (ในอีเมลหรือ GDocs ของคุณ) รายงานความผิดพลาดของพวกเขา ขอโทษด้วยสำหรับภาษาอังกฤษที่ไม่ดีของฉัน


4

หากคุณกำลังมองหาเครื่องมือการรายงานความผิดพลาดพื้นฐานลองcrashlytics

หากคุณต้องการเป็นเครื่องมือการรายงานที่สูงขึ้นกร้าGryphonet จะบันทึกข้อผิดพลาดทั้งหมดที่เกิดขึ้นพร้อมกับบรรทัดรหัสที่ทำให้เกิดความผิดพลาดพร้อมกับเครื่องหมายอัตโนมัติที่แสดงขั้นตอนที่ผู้ใช้ทำก่อนที่จะเกิดความผิดพลาดและอีกมากมาย

โชคดี!



2

ฉันได้สร้างห้องสมุดนี้เพื่อแก้ปัญหาของคุณทั้งหมด Crash Reporter เป็นเครื่องมือที่มีประโยชน์ในการดักจับการล่มทั้งหมดของคุณ

เพียงเพิ่มการพึ่งพานี้และคุณก็พร้อมที่จะไป

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

ค้นหาข้อขัดข้องทั้งหมดในอุปกรณ์ในพื้นที่และแก้ไขตามที่คุณสะดวก บันทึกข้อขัดข้องโดยใช้รูปแบบวันที่และเวลาง่ายต่อการติดตาม นอกจากนี้ยังมี API สำหรับการจับภาพบันทึกข้อยกเว้นโดยใช้วิธีการด้านล่าง

CrashRepoter.logException(Exception e)

คลาส Java ที่คุณใช้เพื่อรับ Crash Logs ของอุปกรณ์คืออะไร?
Xenolion

Thread.UncaughtExceptionHandler อินเตอร์เฟสถูกใช้เพื่อดักจับการล่มทั้งหมดที่ไม่สามารถจัดการได้ นี่คือการดำเนินการสำหรับเดียวกันgithub.com/MindorksOpenSource/CrashReporter/blob/master/...
บาหลี

ตกลงตรวจสอบสิ่งนี้ ... ! ขอบคุณ
Xenolion

2

นี่เป็นวิธีการแก้ปัญหาที่สามารถช่วยคุณถ่ายโอนบันทึกทั้งหมดไปยังไฟล์ข้อความได้

adb logcat -d > logs.txt


0

หากคุณกำลังมองหาบันทึกข้อผิดพลาดขณะที่โทรศัพท์ของคุณเชื่อมต่อกับคอมพิวเตอร์ให้ใช้มุมมอง DDMS ใน Eclipse และรายงานจะอยู่ที่นั่นใน LogCat ภายใน DDMS เมื่อแอปของคุณขัดข้องขณะทำการดีบัก


0

1) เสียบโทรศัพท์ผ่าน USB (เปิดใช้งานตัวเลือกการดีบักสำหรับนักพัฒนา)

2) เปิด Terminal และไปที่ Android SDK ของคุณ (สำหรับ Mac):

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

3) Logcat จากไดเรกทอรีนั้น (ในเครื่องของคุณ) เพื่อสร้างการไหลของบันทึกอย่างต่อเนื่อง (สำหรับ Mac):

./adb logcat

4) เปิดแอปของคุณที่เกิดปัญหาเพื่อสร้างบันทึกข้อผิดพลาด

5) Ctrl + C เพื่อหยุดเทอร์มินัลและค้นหาบันทึกที่เกี่ยวข้องกับแอปที่ขัดข้อง มันอาจพูดอะไรบางอย่างดังต่อไปนี้:

AndroidRuntime: FATAL EXCEPTION: main


0

จากPOSTนี้ให้ใช้คลาสนี้แทน "TopExceptionHandler"

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) {
}

}

.....

ในไฟล์คลาส Java เดียวกัน (กิจกรรม) .....

Public class MainActivity.....

.....

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

.....


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.