2013-07-07 35 views
7

Tôi đang phát triển một ứng dụng và mỗi lần một trong các chuỗi công nhân nền của tôi sẽ có ngoại lệ không bị loại trừ theo một loại này hoặc cách khác. Những ngoại lệ này làm hỏng chuỗi đó, nhưng vì nó không nằm trên chuỗi giao diện người dùng mà Ứng dụng tiếp tục chạy. Làm thế nào tôi có thể bắt buộc các ngoại lệ không bị bắt buộc này trong các chủ đề nền làm hỏng toàn bộ ứng dụng? Nó sẽ là tốt đẹp nếu cùng một thông tin sụp đổ theo ngữ cảnh (chẳng hạn như dấu vết ngăn xếp) có sẵn.Android: Force Crash with Uncaught Exception trong Chủ đề

Tôi muốn làm điều này để khi tôi phát hành ứng dụng cho người thử nghiệm, nó không trở nên không phản hồi. Thay vào đó, khi các chủ đề nền có một ngoại lệ uncaught App sẽ đi đến xử lý tai nạn của nó và gửi cho tôi một báo cáo (Tôi đang sử dụng ACRA, nhưng điều đó không quan trọng). Đó là tốt hơn so với một ứng dụng âm thầm thất bại.

Trả lời

0

bạn có thể bắt ngoại lệ không bị bắt buộc của mình trong lớp thực hiện java.lang.Thread.UncaughtExceptionHandler.

  • tạo ra một lớp mà thực hiện các UncaughtExceptionHandler và đưa hành vi mà bạn muốn trong uncaughtException chức năng overidden.
    bạn có thể thực hiện trong chức năng này bất kỳ hành vi nào bạn muốn như gửi nhật ký tới máy chủ, hiển thị hộp thoại tùy chỉnh sự cố cho người dùng, v.v.
  • trong hoạt động/chủ đề thêm Thread.setDefaultUncaughtExceptionHandler(); và đưa ra một ví dụ về lớp xử lý ngoại lệ của bạn.


+0

Điều này không hoạt động đối với tất cả triển khai Executor. Một số người trong số họ không gọi người xử lý. Bạn phải ghi đè 'afterExecute' và rethrow RuntimeException hoặc Error từ đó để buộc nó sụp đổ. – Monstieur

2

Cuối câu trả lời, nhưng tôi đã tự hỏi mình những câu hỏi tương tự.

Chúng tôi sử dụng Crashlytics trong sản xuất, nhưng nếu ứng dụng được xây dựng để phát triển, một số xác nhận được bật và ghi lỗi thực sự ném, để nhà phát triển có thể phát hiện bất kỳ hành vi không chính xác nào.

Nhưng khi bạn nhận xét, việc ném lỗi trong chuỗi nền không làm hỏng ứng dụng.

Để đảm bảo ứng dụng gặp sự cố ngay lập tức khi xây dựng cho phát triển, chúng tôi chỉ cần sử dụng Trình xử lý trên looper chính để ném ngoại lệ lên chuỗi chính.

Có vẻ một chút như thế này:


public static void assertTrue(boolean condition, String msg) { 
    if (condition) { 
     return; 
    } 

    final IllegalStateException e = new IllegalStateException(message); 
    if (BuildConfig.RELEASE) { 
     Crashlytics.logException(e); 
     return; 
    } 

    Log.e("ASSERT", message, e); 
    if (Looper.getMainLooper() != Looper.myLooper()) { 
     mMainThreadHandler.post(new Runnable() { 
      @Override 
      public void run() { 
       throw e; 
      } 
     }); 
    } 

    throw e; 
} 
+0

Trong khi điều này trông giống như một giải pháp đầy hứa hẹn, một vài điều không rõ ràng với tôi: 1. Làm thế nào để tránh lỗi Intellij cho "ngoại lệ chưa bắt buộc" trong chạy() 2. Bạn lấy mainThreadHandler trong ngữ cảnh tĩnh này ở đâu? –

0

gốc phiên bản dưới đây

Trên thực tế, sau khi thử nghiệm thêm nữa tôi đã phát hiện ra rằng bạn có thể đơn giản hóa mã của bạn bằng cách chỉ bàn giao trừ vào chủ đề chính của bạn trực tiếp.

public static <T extends Exception> void throwOnMainThread(T exception) { 
    Thread mainThread = Looper.getMainLooper().getThread(); 
    mainThread.getUncaughtExceptionHandler().uncaughtException(mainThread, exception); 
} 

Điều này sẽ làm hỏng chuỗi chính từ mọi nơi và an toàn để gọi ngay cả khi không đặt UncaughtExceptionHandler tùy chỉnh.

Original câu trả lời:

Xem xét các phương pháp tĩnh sau cho đâm thread chính từ một sợi nền:

public static <T extends Exception> void throwOnMainThread(final T exception) { 
    Handler mainThreadHandler = new Handler(Looper.getMainLooper()); 
    mainThreadHandler.post(new Runnable() { 
     @Override 
     public void run() { 
      Thread currentThread = Thread.currentThread(); 
      currentThread.getUncaughtExceptionHandler().uncaughtException(currentThread, exception); 
     } 
    }); 
} 

tiên chúng ta có được một Handler cho Chủ đề chính thông qua Looper chính.Sau đó, chúng tôi gửi một Runnable mà sẽ gọi UncaughtExceptionHandler của chủ đề đó và trao cho nó ngoại lệ của chúng tôi.

Đặt điều này vào một lớp học utils và bạn sẽ có thể ném ngoại lệ về chủ đề chính từ cơ bản ở bất cứ đâu.

Đâm các chủ đề chính sau đó có thể đạt được bằng cách sử dụng

ThreadUtils.throwOnMainThread(new RuntimeException()); 

ví dụ.

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