Làm thế nào để có được bản ghi sự cố Android?


155

Tôi có một ứng dụng không có trên thị trường (được ký với chứng chỉ gỡ lỗi), nhưng muốn nhận dữ liệu nhật ký sự cố, bất cứ khi nào ứng dụng của tôi gặp sự cố. Tôi có thể tìm thấy nhật ký tại sao ứng dụng của tôi bị sập?

Câu trả lời:


139

Nếu ứng dụng của bạn đang được người khác tải xuống và gặp sự cố trên các thiết bị từ xa, bạn có thể muốn xem xét thư viện báo cáo lỗi Android (được tham khảo trong bài đăng SO này ). Nếu chỉ trên thiết bị cục bộ của riêng bạn, bạn có thể sử dụng LogCat. Ngay cả khi thiết bị không được kết nối với máy chủ khi xảy ra sự cố, kết nối thiết bị và ra adb logcatlệnh sẽ tải xuống toàn bộ lịch sử logcat (ít nhất là trong phạm vi mà nó được đệm thường là một dữ liệu nhật ký, nó không phải là vô hạn). Có một trong những lựa chọn trả lời câu hỏi của bạn? Nếu không bạn có thể cố gắng làm rõ những gì bạn đang tìm kiếm thêm một chút?


2
bạn có thể chi tiết làm thế nào để sử dụng lệnh logcat adb? Tôi có chạy cái này trong thư mục / SDK / tools không? Có cờ nào tôi cần lưu ý không? v.v.
jesses.co.tt

2
@ jesses.co.tt Đúng, chỉ cần chạy adb logcattừ bất kỳ thư mục adb nào được đặt. Ngoài ra, bạn có thể sử dụng các công cụ SDK có trong plugin Eclipse
Chris Thompson

2
Crashlytics là phần mềm ghi nhật ký ngoại lệ từ xa tốt nhất mà tôi từng sử dụng. Nó đi ra trong tất cả các ứng dụng của tôi, kiểm tra xem nó ra.
Jacksonkr

adb.exe được đặt tại $SDK_DIR/platform-tools/. Để hiển thị lỗi:.\adb.exe logcat -v time *:E
Harun

53

Cách để thực hiện việc này là triển khai Thread.UncaughtExceptionHandlergiao diện và chuyển nó vào Thread.setDefaultUncaughtExceptionHandler()lúc bắt đầu Hoạt động của bạn onCreate(). Đây là lớp thực hiện 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);
    }
}

Lưu ý Chúng tôi để cho defaultUEH của khung Android xử lý nó.

Ở đầu Hoạt động của bạn, hãy đăng ký một thể hiện của lớp trên như thế này:

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

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

Trình xử lý này lưu dấu vết trong một tập tin. Khi nàoReaderScope khởi động lại lần sau, nó sẽ phát hiện tệp và nhắc người dùng nếu anh ta / cô ta muốn gửi email cho nhà phát triển.

Để gửi email theo dõi ngăn xếp, thực thi mã sau để đóng gói trong email.

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

Hoặc bạn cũng có thể sử dụng Hệ thống báo cáo lỗi ACRA. Chỉ cần bao gồm ACRA.jar trong libs dự án của bạn và sử dụng đoạn mã dưới đây trước khi khai báo lớp hoạt động trình khởi chạy của bạn

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

hoặc Bạn có thể thử điều này từ bảng điều khiển: -

adb logcat -b crash 

Không phải là dòng defaultUEH.uncaughtException (t, e); gọi phương thức unsaughtException () vô hạn?
Mickael Bergeron Néron

@ MickaelBergeronNéron no - nó sẽ chỉ chuyển cùng một throwable sang trình xử lý cấp cao nhất.
dạngBCE


36

Bạn có thể thử điều này từ bảng điều khiển:

adb logcat --buffer=crash 

Thông tin thêm về tùy chọn này:

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

Nếu bạn đang sử dụng Eclipse, hãy đảm bảo bạn sử dụng gỡ lỗi và không chạy. Đảm bảo bạn đang ở trong phối cảnh gỡ lỗi (trên cùng bên phải) Bạn có thể phải nhấn 'Tiếp tục' (F8) một vài lần để nhật ký in. Nhật ký sự cố sẽ nằm trong cửa sổ Logcat ở dưới cùng nhấp đúp cho toàn màn hình và đảm bảo bạn cuộn xuống dưới cùng. Bạn sẽ thấy văn bản màu đỏ bị lỗi, dấu vết sự cố sẽ giống như

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

Các phần quan trọng cho cái này là

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)

những người cho chúng tôi biết đó là một mảng nằm ngoài giới hạn trên dòng 13 của main.java trong phương thức onCrate.


9

Bạn có thể sử dụng Apphance. Đây là một dịch vụ đa nền tảng (hiện chủ yếu là Android, iOS với các nền tảng khác đang hoạt động) cho phép gỡ lỗi từ xa mọi thiết bị di động (Android, iOS hiện tại - những thiết bị khác đang được phát triển). Nó không chỉ là một crashlog, trên thực tế nó còn hơn thế nữa: ghi nhật ký, báo cáo các vấn đề của người kiểm tra, crashlog. Mất khoảng 5 phút để tích hợp. Hiện tại bạn có thể yêu cầu quyền truy cập vào phiên bản beta kín.

Tuyên bố miễn trừ trách nhiệm: Tôi là CTO của Polidea, một công ty đứng sau Apphance và đồng sáng lập của nó.

Cập nhật: Apphance không còn là phiên bản beta đã đóng! Cập nhật 2: Apphance có sẵn như là một phần của http://applause.com cung cấp


2
Tôi chỉ cần thử apphance và thích nó. Các tài liệu đã bỏ lỡ một điểm quan trọng khi tích hợp lib apphance vào ứng dụng của bạn; với phiên bản mới nhất của ADT Eclipse, bạn phải đặt apphance.jar vào libsthư mục như câu trả lời SO này giải thích. Cam kết github này hiển thị các thay đổi tôi cần thực hiện cho ứng dụng WorldMap của mình để sử dụng apphance.
JohnnyLambada

@HohnnyLambada Cảm ơn bình luận của bạn. Chúng tôi đã cập nhật các tài liệu để làm cho điều này rõ ràng hơn.
Piotr Duda

12
điều này không nên có quá nhiều mũi tên lên, nó có giá gấp 10 lần so với hầu hết ngân sách phát triển (2.500 đô la một tháng!)
user26676

apphance là 404 tại ngày bình luận này.
DaveP

Chính xác. Nó đã bị bẻ cong từ lâu bởi uTest, sau đó đổi thương hiệu toàn bộ dịch vụ của họ (bao gồm cả tính năng của Aphhance) thành Vỗ tay. Vì vậy, bây giờ là vỗ
tay.com


4

Bạn có thể sử dụng ACRA từ điều này . Bao gồm thư viện này cho các dự án của bạn và định cấu hình nó, bạn có thể nhận được (vào email hoặc gdocs) các báo cáo sự cố của họ. Xin lỗi vì tiếng Anh của tôi không tốt.


4

Nếu bạn đang tìm kiếm một công cụ báo cáo sự cố cơ bản, hãy thử crashlytics .

Nếu bạn muốn có một công cụ báo cáo nâng cao hơn, Checkout Gryphonet . Nó ghi lại tất cả các sự cố xảy ra cùng với dòng mã chính xác gây ra sự cố cùng với các điểm đánh dấu tự động cho bạn thấy các bước người dùng đã thực hiện trước khi xảy ra sự cố và hơn thế nữa.

Chúc may mắn!



2

Tôi đã tạo ra thư viện này để giải quyết tất cả các vấn đề của bạn. Crash Reporter là một công cụ tiện dụng để ghi lại tất cả các sự cố của bạn và đăng nhập chúng vào thiết bị cục bộ

Chỉ cần thêm phụ thuộc này và bạn tốt để đi.

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

Tìm tất cả các sự cố của bạn trong thiết bị cục bộ và khắc phục chúng một cách thuận tiện. Sự cố được lưu bằng định dạng ngày và giờ dễ theo dõi. Thêm vào đó, nó cũng cung cấp API để chụp Ngoại lệ được ghi bằng phương pháp bên dưới.

CrashRepoter.logException(Exception e)

Lớp Java mà bạn đã sử dụng để lấy Nhật ký sự cố của thiết bị là gì?
Xenolion

Giao diện Thread.UncaughtExceptionHandler được sử dụng để ghi lại tất cả các sự cố chưa được xử lý. Đây là cách triển khai cho cùng một github.com/MindorkOpenSource/CrashReporter/blob/master/ .
Bali

Được rồi, hãy kiểm tra cái này ...! Cảm ơn
Xenolion

2

Đây là một giải pháp có thể giúp bạn đổ tất cả các bản ghi vào một tệp văn bản

adb logcat -d > logs.txt


0

Nếu bạn chỉ tìm kiếm nhật ký sự cố trong khi điện thoại của bạn được kết nối với máy tính, hãy sử dụng chế độ xem DDMS trong Eclipse và báo cáo có ngay trong LogCat trong DDMS khi ứng dụng của bạn gặp sự cố trong khi gỡ lỗi.


0

1) Cắm điện thoại qua USB (bật tùy chọn gỡ lỗi dành cho nhà phát triển)

2) Mở Terminal và điều hướng đến SDK Android của bạn (dành cho máy Mac):

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

3) Logcat từ thư mục đó (trong thiết bị đầu cuối của bạn) để tạo ra một dòng nhật ký không đổi (cho Mac):

./adb logcat

4) Mở ứng dụng của bạn gặp sự cố để tạo nhật ký sự cố

5) Ctrl + C để dừng thiết bị đầu cuối và tìm kiếm các bản ghi liên quan đến ứng dụng gặp sự cố. Nó có thể nói một cái gì đó như sau:

AndroidRuntime: FATAL EXCEPTION: main


0

Dựa trên POST này , sử dụng lớp này để thay thế "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) {
}

}

.....

trong cùng một tệp lớp java (Hoạt động) .....

Public class MainActivity.....

.....

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

.....


-1

Hãy thử ứng dụng đăng nhập Carsh từ Android.

sử dụng liên kết để tải xuống ứng dụng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.