2009-07-01 37 views
13

Tôi đã tạo một ứng dụng sử dụng camera và trong quá trình thực hiện ứng dụng, màn hình luôn bật.Android: Cách giải phóng tài nguyên khi ứng dụng chấm dứt?

Trong phương thức onCreate() tôi đã thêm khóa:

final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); 
this.mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag"); 
this.mWakeLock.acquire(); 

Và đây là overriden onStop() phương pháp:

@Override 
protected void onStop() { 

    if(mWakeLock.isHeld()) 
    { 
     mWakeLock.release(); 
    } 

    super.onStop(); 
} 

Nhưng sau khi kết thúc ứng dụng màn hình vẫn còn trên tất cả các thời gian và nếu tôi chạy ứng dụng máy ảnh, nó gặp lỗi xuất hiện rõ ràng vì tài nguyên máy ảnh không được phát hành.

Có ai biết cách giải phóng tất cả các tài nguyên khi chấm dứt ứng dụng không?

Trả lời

13

Tôi sẽ di chuyển khóa từ OnCreate() sang OnResume(). Bạn muốn khóa trong suốt thời gian hiển thị của Hoạt động, không phải toàn bộ thời gian của Hoạt động. Bạn Activity chắc chắn vẫn đang chạy với một Activity khác đang chạy trước nó.

Tôi sẽ chuyển bản phát hành sang OnPause(). OnPause() là điểm sớm nhất mà ứng dụng của bạn thường bị hệ điều hành giết.

Ngoài ra, tôi sẽ không kiểm tra xem tôi có khóa trước khi phát hành hay không. Nếu bạn sử dụng OnResume() để lấy khóa; isHeld phải luôn đúng trong OnPause().

+1

gợi ý của bạn cho không kiểm tra trạng thái khóa là ok nếu phát hành() là một hoạt động idempotent. Nếu không, nó xấu. Điều gì sẽ xảy ra nếu ứng dụng không nhận được khóa và muốn đóng ứng dụng? – Thushan

+1

Nhận xét tuyệt vời. Tôi đã xem mã nguồn Android. Có vẻ như cách duy nhất bạn không thể lấy khóa là nếu bạn làm sai cuộc gọi của mình, trong trường hợp đó, nhật ký sẽ báo lỗi nhưng không ném ngoại lệ. Nếu bạn gọi bản phát hành() mà không có khóa, nó sẽ ném một ngoại lệ "WakeLock bị khóa". Tài liệu về việc có được() dẫn người ta nghĩ nếu bạn yêu cầu khóa, bạn sẽ nhận được khóa. Nhưng nếu bạn nên kiểm tra, sau đó bạn nên kiểm tra ngay sau khi có được(), không phải sau khi chương trình đã chạy và bạn sắp thoát. – Will

1

Bạn gọi đến đâu là xong()?

Bạn nên phát hành tài nguyên của mình ở chế độ onPause chứ không phải trên onStop. Không có gì đảm bảo rằng onStop sẽ luôn được gọi trước khi hoạt động của bạn bị giết. Nếu hệ thống cần tài nguyên thì nó có thể giết chết hoạt động trước khi onStop được gọi.

Cố gắng đặt nhật ký gỡ lỗi và theo dõi đường dẫn thực hiện khi bạn cho rằng ứng dụng của bạn đang bị chấm dứt.

3

Có vẻ như ứng dụng của bạn không bao giờ gọi phát hành trên Wakelock - có thể là nó ném ngoại lệ sớm hơn trong onStop hoặc ? Tôi sẽ bao gồm một số đăng nhập nơi bạn đang gọi phát hành để xác nhận nó đang được thực hiện.

Trong mọi trường hợp, bạn chắc chắn sẽ muốn di chuyển các phương pháp acquirerelease thành onResume và tương ứng. Mã bạn đã có sẽ chỉ nhận được WakeLock lần đầu tiên ứng dụng của bạn được bắt đầu.

Nhờ xử lý nền của Android, mã của bạn có sự mất cân đối tiềm ẩn. Nếu người dùng nhấn phím chủ để chuyển đổi các ứng dụng, khóa sẽ được giải phóng. Nếu họ chuyển trở lại ứng dụng của bạn trênTạo sẽ không được gọi, do đó, khóa sẽ không bao giờ được mua lại.

Đặt cược tốt nhất của bạn là xây dựng WakeLock trong onCreate (như bạn có), lấy khóa trong onResume và nhả nó trong onPause (bao gồm cả cuộc gọi đến isHeld). Điều này sẽ đảm bảo rằng khóa sẽ được giữ lại bất cứ khi nào ứng dụng của bạn ở mặt trước.

2

Tôi gặp khó khăn khi phát hành dữ liệu khi tôi đang sử dụng OpenGL. Vì vậy, bây giờ, với android.os.Process.killProcess (android.os.Process.myPid()); nó hoạt động giống như tôi muốn !!

Nhờ nghệ thuật

3

tôi sử dụng mWakelock.setReferenceCounted (false), vẫn dunno ý nghĩa của nó, nhưng nó giải quyết của tôi "Wakelock dưới khóa" vấn đề.

Init: OnStart() Acquire: onResume() phát hành: onStop()

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