6

Tôi hỏi this câu hỏi một số thời gian trở lại trên Stackoverflow, câu trả lời làm việc cho tôi, Nó đè handleUncaughtException, tôi lưu các ngoại lệ và ném mặc định Unfortunately app has stopped working, nhưng khi tôi tích hợp này trong ứng dụng của tôi , Tôi đang đối mặt với một vấn đề.Làm thế nào để ghi đè handleUncaughtException mà không thay đổi functionallity nó

Đây là câu trả lời tôi nhận được.

private Thread.UncaughtExceptionHandler defaultExceptionHandler; 

    public void registerCrash(){ 
     defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); 

     Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler(){ 
      @Override 
      public void uncaughtException (Thread thread, Throwable e){ 
       handleUncaughtException (thread, e); 
       if(defaultExceptionHandler != null){ 
        defaultExceptionHandler.uncaughtException(thread, e); 
       } 
      } 
     }); 
    } 

gì nó làm, đầu tiên nó đi để handleUncaughtException (thread, e); i lưu nhật ký sự cố trong phương pháp này, sau đó nó đọc dòng này

if(defaultExceptionHandler != null){ 
    defaultExceptionHandler.uncaughtException(thread, e); 
} 

ở đây chúng tôi ném ngoại lệ còn tự do nữa, vì vậy nó đi để là người đầu tiên một lần nữa, và một lần nữa tiết kiệm ngoại lệ, và điều này đi trong vòng lặp, và ứng dụng sẽ không đáp ứng.

Điều tôi muốn là lưu nhật ký sự cố và sau đó hiển thị thông báo mặc định Unfortunate cho người dùng.

EDIT

Trong lần khởi chạy ứng dụng nó đọc này;

defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); 

Khi ứng dụng bị treo, nó đọc những dòng này

Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler(){ 
    @Override 
    public void uncaughtException (Thread thread, Throwable e){ 

     handleUncaughtException (thread, e); //Custom Method 

     if(defaultExceptionHandler != null){ 
      defaultExceptionHandler.uncaughtException(thread, e); 
     } 
    } 

Vì vậy, nó đầu tiên đi vào handleUncaughtException() có tôi đã cung cấp thực hiện tùy chỉnh, sau đó nó đi vào này;

if(defaultExceptionHandler != null){ 
    defaultExceptionHandler.uncaughtException(thread, e); 
} 

defaultExceptionHandler không bao giờ là rỗng; Vì vậy, nó đi trong một vòng lặp trong trường hợp nhiều tai nạn.

Tôi đã thử thêm count ở đó, nhưng mỗi lần là 0.

+0

'Vì vậy, nó đi trong một vòng lặp trong trường hợp nhiều Bạn có thể chỉ ra một tình huống xảy ra? Điều gì khiến một ngoại lệ khác xảy ra? – azizbekian

+0

@azizbekian: Tôi không thể tìm ra các bước để khôi phục lại nó. Điều này không xảy ra mọi lúc, nhưng đôi khi – Kirmani88

+0

phương thức defaultExceptionHandler là gì. Đó có phải là phương pháp của riêng bạn? nếu có, hãy viết mã phương thức đó. Và mã phương thức postUUaughtException (thread, e) quá –

Trả lời

1

Giải thích rất có thể là phương pháp registerCrash() của bạn đang được gọi hai lần.

Lần đầu tiên, bạn đăng ký Handler 1; không có trình xử lý mặc định nào tại thời điểm này, do đó, nó đặt defaultExceptionHandler thành null. Lần thứ hai, bạn đăng ký Handler 2 và sau đó cập nhật defaultExceptionHandler để trỏ đến Handler 1.

Trên ngoại lệ không bắt buộc, trước tiên, Handler 2 được gọi. Nó gọi phương thức xử lý tùy chỉnh của bạn, sau đó gọi defaultExceptionHandler, hiện trỏ đến Handler 1.

Handler 1 được gọi. Nó gọi phương thức xử lý tùy chỉnh của bạn lần thứ hai, sau đó nó gọi defaultExceptionHandler, hiện trỏ đến chính nó. Bước này lặp lại cho đến khi tràn ngăn xếp của bạn.

Tôi đề xuất hai thay đổi. Trước tiên, thêm một bảo vệ để đảm bảo bạn chỉ đăng ký trình xử lý sự cố của bạn một lần. Thứ hai, không lưu trữ trình xử lý dự phòng trong một trường; nắm bắt nó trong một đóng cửa để giá trị nhìn thấy bởi xử lý của bạn không bao giờ thay đổi.

private static final AtomicBoolean CRASH_HANDLER_REGISTERED = new AtomicBoolean(); 

public void registerCrash() { 
    if (CRASH_HANDLER_REGISTERED.compareAndSet(false, true)) { 
     final Thread.UncaughtExceptionHandler defaultHandler = 
      Thread.getDefaultUncaughtExceptionHandler(); 

     Thread.setDefaultUncaughtExceptionHandler(
      new Thread.UncaughtExceptionHandler() { 
       @Override 
       public void uncaughtException(Thread thread, Throwable e) { 
        handleUncaughtException(thread, e); // Custom Method 

        if (defaultHandler != null) { 
         defaultHandler.uncaughtException(thread, e); 
        } 
       } 
      } 
     ); 
    } 
} 
0

Tôi đề nghị bạn thử cách tiếp cận khác, tránh trọng ngoại lệ, bắt nó và truy xuất mã lỗi, và làm điều này:

when x code with x conditions verify, do that

Các vấn đề liên quan