I know android use wake lock to keep cpu running or screen on.
It's obvious that screen wake lock prevents the user active timer from turning off the screen after a period of user inactivity.
But I'm wondering when exactly will the cpu wake lock take effect.
1.If I create a new thread and keep draining cpu in background with out any wake lock, turn off the screen will not stop it. Will it stop and when will it stop?
2.What about a thread scheduled with Timer.schedule()?
3.It leads to another question, if I keep a long socket connection in a service, which is blocked at socket.read(). Do I have to acquire a wake lock to make sure the service will be wakeup when the socket receives any data form remote?
Thanks.
Answers to all your sub-questions
Android sleeps when no wake-lock is active. It does not matter what processes and threads are running it will still sleep. That means if your thread or some other process out there has not activated a wake lock your thread will not execute and hence will not drain any battery. The thread will be made active only when some other process acquires a wakelock.
Same is applicable to the Timer.schedule(). Say you write a Timer that executes every second but without any wake-lock, and say android goes to sleep for 10 seconds. When it wakes p on 11th second it will identify that your timer has expired 10 times it will simply discard the9 instances and execute it only once. If you want very reliable timers you will have to either obtain a wake lock or user AlarmTimer.
Yes.
What i learn from different functionality related to Wake-Lock , Android System will never sleeps, if it sleeps you will not get SMS , Call i.e Android will not run only OS level task when it goes on sleep.
Wake-lock is a mechanism where any application can request system to have the device stay on for him. Application can perform operation on background despite user haven`t move to launch that application.
For 1 & 2 Akshar has explained correctly.
3. As to perform any operations in your application while system is in sleep state(only OS level task are runnning) , you first have to request wake-lock from system and then only application can run its operations. After completing operations you should release the wake lock so that system can move to managing OS level tasks.
Related
In our Android app, we have UI component and core C++11 module. A thread is running based on std::chrono::system_clock::time_point, such as below:
while(this->m_ConditionVariable.wait_until(lock, this->m_Object.to_time_point())
== std::cv_status::no_timeout)
{
// ... handle any notify() or arbitrary sleep breaks
}
Execute(); // <--- not being called consistently
Now, we are testing with 1 minute time_point. If the app is in use, then the Execute() is invoked as expected. However, if the app is moved to background or if even the screen is locked, then the Execute()-s behavior is not consistent.
Sometimes, it may work properly every minute for 15 mins and after that it will be invoked after 2 minutes or 3 minutes or 10 minutes, instead of fixed 1 minute. Using debugs, we checked that, the time_point supplied is proper.
Suppose if we run the app in debug mode (using Android Studio) then it works fine even in background and screen locked mode.
Does Android have any threading priority for the app running in background?
Update 1: Basically the background thread is collecting location information. I came across below question, which suggests that in Android, when the phone is locked, the thread execution is halted. Am I stuck to that problem?
App seems to stop working when the screen goes to sleep
Update 2: With partial Wake lock, it works fine. But not sure if that's a good solution. If that's the only way, then I would appreciate strategy for how to use it optimally.
Update 3: If I replace wait() with smaller sleep(), then it works fine even without any Android wake lock. However we are yet to do regressive testing on it.
When the device is idle, the CPU is stopped and any thread running is paused (C++ or Java). If it wakes up for any reason your C++ thread will start working again, hence the random behavior: Other apps or services might wake-up the device every now and then.
Adding a partial wake lock works in your case but that will prevent the CPU from going idle, which will cause some battery drain. If you don't care you can use this approach, if battery live is an issue, you can use the Java alarm API to wake up the device on a regular basis. Then the java API can call the C++ code through JNI.
Android documentation for repeated alarms: https://developer.android.com/training/scheduling/alarms.html
For the update 3, using a small sleep rather than wait(), I suspect android is not going in idle mode while a thread is running, maybe it waits for a small timeout without any thread active before it goes idle. This approach will have the same effect on the battery drain than the wake lock.
I have countdown timer ticking in service. It updates UI through broadcast.
All works good, but I don't know how to wake device if it were in sleep state (user pressed the power button or enough time elapsed)?
Maybe you should use wake lock to prevent CPU to go to sleep, look at this question
Wake locks android service recurring and this How can I keep my Android service running when the screen is turned off?
I am developing an application that uses a Service as Contdown. When the user starts the countdown from the activity and the activity goes in background after the sleep button is pressed, I am using this Service to continue the countdown. When the count is finished the Service shows a notification with ringtone.
I use wait() "to count" the time in the Service. The strange behavior occurs when I use the application on a real device, but in debug mode. When Eclipse debugger is attached, the Service works well; when I test the application on the device without Eclipse debugger attached, the Service doesn't show the notification when the countdown is finished, unless the sleep button is repressed and the monitor is activated - then the notification and the ringtone are activated.
Can anyone can explain what causes this strange behavior? Maybe the issue is is related to Wake lock or a similar construct?
I use wait() "to count" the time in Service.
That is poor programming practice. Time elapses even without your tying up RAM to do it.
Anyone can explaine why this strange behavior?
The device fell asleep. This is normal, and desirable, behavior, to conserve battery life. With the USB cable plugged in, the device does not need to fall asleep, and if you checked the appropriate option in Developer Options, the device specifically will not fall asleep while plugged in.
Maybe is connected with Wake lock
Please do not use a WakeLock to keep the device awake for you to watch the clock tick by. Please use AlarmManager to get control when the countdown period is over. You can use a _WAKEUP-style alarm to arrange to wake up the device, and your BroadcastReceiver that gets control at that point can "launch a notification and ringtone". As a bonus, you can get rid of your service, so that your app can be better behaved on the user's device.
wait() calls are not guaranteed to wait for the right amount of time if the device goes to sleep. You should use AlarmManager to trigger your countdown timer instead.
I want to run a thread to do some work in the background (from a service that acquired a wakelock). after my thread finish work then it will stop the service.
My concerns are :
1- Do i need to require a wakelock in the thread that was started in the service?
2- Can the system kill my thread while leaving my service running?
3- if 2 is the case how could i stop my service (can i give the service a timeout time that it will die after it)
WakeLocks are, as I understand applied to the Android component (e.g. service, activity, etc.) and all its associated threads. So you would not have to aquire a new wakelock in your thread. You could prove this by passing the aquired lock and calling isHeld from the started thread.
You should consider a partial wakelock, this will concern only keeping the CPU running, regardless of the screen or keyboard activity. Since this is a service I assume you don't care whether the screen stays on.
Note that it states here: If you hold a partial wakelock, the CPU will continue to run, irrespective of any timers and even after the user presses the power button. In all other wakelocks, the CPU will run, but the user can still put the device to sleep using the power button.
Edit: Also, even though you can do it the way you suggested, it might be better to only aquire and release the wakelock in the child thread for battery consumption purposes. And if you are needing to use WiFi for this work a WiFiLock may also be required.
So in my "Home" activity in my Android app, I have a non-deamon thread that is constantly running in the background that checks a blog for new posts every 30 minutes or so to fire notifications. It works fine when I make the thread sleep just for a few seconds for testing purposes to make sure that it is indeed working in the background, but in the actual phone, when the event is supposed to fire after half an hour, it just doesn't. So my question is, when I do *Thread.sleep(30_MINUTES)* does the android system kill it or something for being an inactive thread for too long? Does android kill sleepy threads?
Why don't you try AlarmManager to fire your polling code every 30 minutes ? Once the polling is done re-schedule if for the next 30 minutes. AlarmManager is much more reliable than making the threads to sleep
OK, so the problem was solved. What was causing the problem was that in Android when you put a Thread to sleep for let's say 30 minutes, when the device goes to sleep (the screen turns off after inactivity on the phone) the CPU goes into a so called "deep sleep state" which causes the thread's counter -that wakes the thread wake up- to pause while the screen is off. This means that when you say Thread.sleep(500000) for example, those 500000 milliseconds are counted only when the phone is awake. The solution is to use AlarmManager and a BroadcastReceiver to run the code periodically.
Here's a simple guide on how to use AlarmManager with a BroadcastReceiver: http://justcallmebrian.com/?p=129
I am not sure what you are doing in your coding but definitely android system does not kill a thread on its own whether sleepy or not doesnt matter.
What exactly is happening during this time? I believe the only situation in which what you're describing (using the technique you describe) would work reliably is if both (a) your activity (or another activity or service that runs in the same process) is the foreground activity for the entire life of the thread and (b) there's a wakelock preventing the CPU from sleeping.
Android may not kill individual threads, but it absolutely can and will kill processes based on the process lifecycle.