2013-04-08 22 views
10

Tôi có một thiết lập đơn giản:Android đóng băng khi có một NullPointerException trong OnClickListener.onClick (các nhiệm vụ khác không thể bắt đầu)

  • CrashHandler - một lớp mà thực hiện Thread.UncaughtExceptionHandler;
  • CrashActivity - hoạt động có thể gửi báo cáo của người dùng;
  • MainActivity - ứng dụng chính mà người dùng nên tương tác.

Khi có một ngoại lệ còn tự do trong MainActivity hoặc bất kỳ chủ đề của nó, các CrashHandler chặn nó và tạo ra một thông báo với ý định để bắt đầu CrashActivity:

Intent it = new Intent("CrashReporter" + SystemClock.currentThreadTimeMillis()); 
it.setClass(context, CrashActivity.class); 
it.setFlags(it.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); 

Trong lúc này chương trình Android thông báo "Ứng dụng bị lỗi", người dùng nhấp vào OK, ứng dụng đã đóng, sau đó người dùng có thể nhấp vào notification. Nếu nhấp vào notification, CrashActivity sẽ bắt đầu và hiển thị.

Mã này đã hoạt động trong một thời gian dài trong nhiều tình huống khác nhau (treo trên chủ đề chính, gặp sự cố trong handler, lỗi trên nền thread ...). Tuy nhiên, gần đây tôi đã phát hiện ra rằng nó KHÔNG LÀM VIỆC nếu ngoại lệ được ném trong phương pháp OnClickListener.onClick trong trình nghe được gắn vào một button trong MainActivity. Tình huống như sau:

  1. Tôi thực thi mã cố ý ném NullPointerException;
  2. CrashHandler chặn nó và tạo một notification (được hiển thị);
  3. Android KHÔNG hiển thị bất kỳ thư nào (ví dụ: không có "Ứng dụng bị lỗi", sẽ hiển thị);
  4. MainActivity bị đóng băng;
  5. NẾU người dùng nhấp vào thông báo để khởi chạy CrashActivity, màn hình màu đen được hiển thị và mọi thứ bị đóng băng (hoạt động mong muốn không được hiển thị).

Logcat cho thấy rằng có một thời gian chờ ngày khởi động, ngay cả trước khi OnCreate hoặc bất kỳ mã của tôi:

I/ActivityManager(11826): START u0 {act=CrashHandler1196 flg=0x14000000 cmp=mycompany.myapp/.CrashActivity bnds=[0,102][720,230] (has extras)} from pid -1 
W/KeyguardViewMediator(11826): verifyUnlock called when not externally disabled 
W/ActivityManager(11826): Activity pause timeout for ActivityRecord{41f4d988 u0 mycompany.myapp/.MainActivity} 
W/ActivityManager(11826): Launch timeout has expired, giving up wake lock! 
W/ActivityManager(11826): Activity idle timeout for ActivityRecord{4225eeb8 u0 mycompany.myapp/.CrashActivity} 
  • Nếu trước khi nhấp vào notification tôi giết các ứng dụng từ ADB, các notification công trình hoàn hảo .
  • Nếu trước khi nhấp vào notification Tôi làm cho một số nhấp chuột và cử chỉ trên ứng dụng đông lạnh, sau một vài giây tôi nhận được một thông điệp về một ANR:

    E/ActivityManager(11826): ANR in mycompany.myapp (mycompany.myapp/.MainActivity) 
    E/ActivityManager(11826): Reason: keyDispatchingTimedOut 
    E/ActivityManager(11826): Load: 0.63/0.57/0.49 
    
  • Nếu tôi bấm "yes, giết nó", và sau đó nhấp vào notification, nó hoạt động hoàn hảo.

  • Nếu tôi thêm System.exit (-1) trong CrashHandler ngay sau khi tạo thông báo, ứng dụng sẽ thoát ngay lập tức và thông báo hoạt động hoàn hảo (rất tiếc, tôi không thể sử dụng giải pháp này trong sản xuất).

Tôi có hai câu hỏi:

  1. Tại sao một NullPointer exception trong OnClickListener.onClick không gây ứng dụng sụp đổ, thay vì đóng băng nó cùng với hệ điều hành và ngăn chặn các hoạt động khác từ khi bắt đầu?
  2. Việc cần làm để tránh điều đó nói chung, hoặc ít nhất, làm cách nào để làm cho việc bắt đầu CrashActivity trong các điều kiện này?
+0

Tôi nghĩ bạn nên đăng một số mã của mình từ ** onClick ** để chúng tôi có thể hiểu được. –

Trả lời

0

Nếu không nhìn thấy mã của bạn, bạn nên gỡ lỗi cho bạn lớp CrashHandler. JVM sẽ bỏ qua tất cả các ngoại lệ trong số

void uncaughtException(Thread t, Throwable e) 

"Bất kỳ ngoại lệ nào được phương thức này sẽ bị bỏ qua bởi Máy ảo Java". (JavaDoc).

Tôi nói rằng đây không phải là câu trả lời nhưng nó có thể là câu trả lời, nếu phương pháp này là một ngoại lệ.

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