views:

1516

answers:

6

Hi,

I created an application which uses camera and during the appplication execution the screen is always on.

In the onCreate() method I added the lock:

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

And this is the overriden onStop() method:

@Override
protected void onStop() {

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

 super.onStop();
}

But after the application termination the screen remains on all the time and if I run the camera application it encounters an error which obviously appears because the camera resources are not released.

Does anyone know how to release all resources on application termination?

A: 

Try calling Activity#finish()

/Jaanus

JaanusSiim
Already tried and it doesn't solve the issue.
niko
+1  A: 

Where are you calling finish()?

You should be releasing your resources in onPause and not on onStop. There is no guarantee that onStop will always be called before your activity is killed. If the system needs resources then it may kill the activity before onStop is called.

Try to put debug logs and trace the execution path when you think your application is being terminated.

Prashast
+1  A: 

I would move the lock from OnCreate() to OnResume(). You want the lock during the visible lifetime of the Activity, not the entire lifetime of the Activity. You Activity could definetly still be running with another Activity running in front of it (hold down the home key to see what's running right now).

I would move the release to OnPause(). OnPause() is the earliest point your application should normally be killed by the OS.

Additionally, I wouldn't check to see if I have the lock before releasing. If you use OnResume() to acquire the lock; isHeld should always be true in OnPause().

Will
Your suggestion for not checking for lock state is ok if release() is an idempotent operation. If not, it's bad. What if the app failed to get the lock and want to close the app?
Thushan
Great comment. I looked at the Android source code. It looks like the only way you can't get a lock is if you malform your call, in which case it logs an error but doens't throw an exception.If you call release() without acquiring a lock it will throw a "WakeLock under-locked " exception.The documentation of acquire() leads one to think if you ask for the lock, you'll get the lock. But if you should check, then you should check right after the acquire(), not after the program has been running and you're about to exit.
Will
+1  A: 

It sounds as though your application is never calling release on the Wakelock - is it possible that it's throwing an exception earlier in onStop or onPause? I'd include some logging where you're calling release to confirm it's being executed.

In any case, you'll definitely want to move the acquire and release methods into onResume and onPause respectively. The code you've got will only acquire the WakeLock the first time your application is started.

Thanks the Android's background processing your code has a potential imbalance. If the user presses the home key to switch applications the lock will be released. If they switch back to your app onCreate won't be called, so the lock will never be acquired.

Your best bet is to construct the WakeLock in onCreate (as you have), acquire the lock in onResume and release it in onPause (including the call to isHeld). This will guarantee that the lock will be held whenever your application is in the foreground.

Reto Meier
A: 

I had troubles to release data when I was using OpenGL. So now, with android.os.Process.killProcess(android.os.Process.myPid()); it works just as I want !!

Thanks Art

A: 

I use mWakelock.setReferenceCounted(false), still dunno what it means, but it resolves my "Wakelock under-locked" problem.

Init: OnStart() acquire: onResume() release: onStop()