2011-11-06 26 views
7

Tôi nhận được DeadObjectException trong mã của mình. Dưới đây, tôi mô tả thiết lập của mình và những gì tôi đã cố khắc phục sự cố.Làm thế nào để đối phó với DeadObjectException trên Dịch vụ bị giết?


Một ServiceS được bắt đầu từ ApplicationMột.

ActivityB (từ ứng dụng khác) giao tiếp với dịch vụ mà sử dụng MessengerIBinder giao diện. Hoạt động này cũng được bắt đầu từ cùng một dịch vụ. Trên một nút bấm bên trong hoạt động này, tôi có nghĩa vụ phải gửi một tin nhắn trở lại dịch vụ. Tôi thường xuyên nhận được DeadObjectException khi nhấn nút.

Tôi hiểu rằng nguyên nhân có khả năng nhất cho việc này là - hệ thống đã bị giết và khởi động lại dịch vụ và hoạt động này có tham chiếu cũ. Ngoài ra, tôi đã không tìm thấy nhiều thông tin trực tuyến.

Đây là những gì tôi đã cố gắng:

  • tôi đã sử dụng một startForeground() phục vụ, và tôi có thể thấy rằng các dịch vụ đang chạy (thông báo trong vùng thông báo) liên tục. Tôi vẫn có ngoại lệ.
  • Khi khởi động lại hệ thống, tôi không nhận được ngoại lệ này trong một thời gian.
  • Trường hợp ngoại lệ là gián đoạn. Tôi không có 100% repro. Tuy nhiên, trong trường hợp sau, tôi luôn nhận được ngoại lệ:
    1. Bắt đầu ứng dụng A (thi cũng bắt đầu dịch vụ S).
    2. Bắt đầu hoạt động B, mọi thứ hoạt động tốt.
    3. Khởi động lại dịch vụ bằng cách triển khai lại ứng dụng A.
    4. Điều hướng đến hoạt động B. Ngoại lệ xảy ra.
    5. Tại thời điểm này, nếu tôi khởi động lại hoạt động B, ngoại lệ sẽ biến mất.
  • Điều này khiến tôi kết luận rằng nếu tôi đảm bảo rằng hoạt động B là mới mỗi lần dịch vụ bắt đầu, ngoại lệ này sẽ biến mất. Sau đó tôi đã cố gắng để cung cấp một ý định giết người để hoạt động B, trước khi bắt đầu nó. (Hoạt động có một số BroadcastReceiver và gọi số finish() trong onReceive()). Vấn đề là, nếu hoạt động tạm dừng, Intent sẽ không được gửi đến. Ngoài ra, tôi thấy onDestroy() bị ảnh hưởng, bởi vì Android quản lý vòng đời hoạt động, mục đích không đảm bảo sẽ được phân phối tới nó. Tôi cũng đã thử mở rộng số BaseActivity như được đề cập trong this stackoverflow question.
  • Tôi cũng đã thử đặt FLAG_ACTIVITY_CLEAR_TASK (ngoài thông thường FLAG_ACTIVITY_NEW_TASK), không có kết quả tốt hơn.

Bây giờ, tôi cảm thấy như thể tôi không có lựa chọn. Có ai phải đối mặt với vấn đề tương tự? Có cái gì tôi có thể thử? Có thể bắt ngoại lệ và sau đó rebind dịch vụ?

Trả lời

2

Trong hoạt động B, triển khai giao diện IBinder.DeathRecipient (có thể được bao bọc trong lớp tùy chỉnh) và đăng ký với IBinder từ dịch vụ của bạn qua IBinder.linkToDeath().Gọi lại của bạn sẽ bị trúng khi/nếu Service chết vì một số lý do và Hoạt động B có thể dọn dẹp sạch sẽ bất kỳ sách nội bộ nào giữ nó cũng như gắn lại với dịch vụ.

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