Android threads and timer slow down running when lockscreen - android

First sorry for my english.
I have a problem, and i can't find a solution, it sounds like:
i'm developping an app that's getting my location from gps and send it to a tcp server on pc , and store the data into a listview (for example). I have set a timer that send the location every 2 seconds. Everything works fine even if i connect two clients to server, until the phones gets locked .. then my server receive ugly string ..it seems like the sent-strings it straddles (the string contains parts of data from bought clients, parts are concatenated) .. but when i unlock the phones the server receive normal strings again..
I want to know how to make my app run in the same parameters when lock screen occurs .. Any ideas?

If you are doing this inside an activity or a fragment you are probably having an issue with the lifecycle of your app. If you want to understand the lifecycle, read this documentation article: http://developer.android.com/training/basics/activity-lifecycle/index.html
Doing nothing on your onPause method won't prevent your activity from sleeping, Android can kill your activity anytime.
The proper way to do this would be inside a Service, a service is a special component on Android that is executed independently of what the user is doing or not doing, and in this case, you could create a service that holds a wake lock in order to prevent it from sleeping for the couple of seconds you need to send your data.
An easier solution would be to use something like this Location polling library and suit it to your needs.

When the screen locks your activity is either paused on stopped and it is important you handle these methods so that any interuptions are handled elegantly and without error. Or so the app will continue to run in the background.
If you read up about the activity lifecycle.
During normal app use, the foreground activity is sometimes obstructed by other visual components that cause the activity to pause. For example, when a semi-transparent activity opens (such as one in the style of a dialog), the previous activity pauses. As long as the activity is still partially visible but currently not the activity in focus, it remains paused.
However, once the activity is fully-obstructed and not visible, it stops (which is discussed in the next lesson).
Activity Lifecycle from android.com

Related

Where is the best place to start a long running, application-wide, background task

I have a long running background task that I would like to start when the app launches and shutdown when the application shuts down. I'm already quite aware of the activity life cycle and what gets called when an activity gets created and destroyed.
I'm coming from an iOS background, and over there we have some calls that are made during application startup and shutdown. Is there something similar in the android world? I've searched a lot and all I'm finding are answers relating to an activity, not the entire application.
(Android is relatively new to me, so I may just not know the correct terminology to search for.)
EDIT:
I'll try an be a bit more specific. I have a background task that needs to be continuously running while the user is using the application. It will be streaming data from a server continuously while the application is active. It does not need to run when the application is in the background. It doesn't seem to make sense to me to tie the startup / shutdown of this background process to any one single activity since it may not be the same one activity that starts up when the application becomes active.
I am (possibly mistakenly) assuming that the OS takes care of starting / stopping background threads when the application resumes and pauses. If that is, in fact, the case, then all I really need to do is spin up the background task when the application first launches, i.e. when it is loaded into memory and becomes active for the first time that session.
It doesn't seem to make sense to me to tie the startup / shutdown of this background task to any one single activity since it may not be the same one activity that starts up when the application becomes active.
That's reasonable. It is somewhat difficult to implement, though.
I am (possibly mistakenly) assuming that the OS takes care of starting / stopping background threads when the application resumes and pauses.
You have it exactly backwards. Android pays not one whit of attention to any threads that you fork yourself, directly or via thin wrappers like AsyncTask.
In addition to that point of confusion, you appear to be equating "user switching to another app" with "app shutdown". Those may be the same thing in single-tasking operating systems. They are not the same thing in Windows, OS X, Linux, Android, etc.
So, what you seem to be seeking is having a background thread running doing this streaming work while your UI is in the foreground, and then stop when your UI is in the background. The problem is that there really isn't a straightforward way of accomplishing that in Android.
One close approximation would be to create and register a custom Application class, where you override onTrimMemory(), and stop your background work when you get to TRIM_MEMORY_UI_HIDDEN, TRIM_MEMORY_BACKGROUND, TRIM_MEMORY_MODERATE, or TRIM_MEMORY_COMPLETE -- whichever of those that you encounter first. If, when one of those arrives, you determine that your streaming thread is still outstanding, shut it down.
In terms of startup, you could use onCreate() on that same Application singleton. The problem is that this will be called on any process creation, which may include scenarios in which you do not have UI (e.g., you are responding to some system broadcast, like ACTION_BOOT_COMPLETED), or possibly your process is going to parts of your UI that do not depend on the streaming. If you have none of those scenarios, then onCreate() in Application would be fine. Otherwise, kick off the streaming in onCreate() of whatever activities need it.
While normally we manage long-running threads with a Service, that is for cases where we explicitly want the thread to continue after our UI is in the background. Since you do not want that, you could skip the service.
It depends on what you want to do exactly. When you're just interested in the app starting for the first time you could #Override onCreate().
Or maybe you want to use onResume() as this will get called whenever a user brings the app to the foreground.
But this really depends on what exactly your background task is doing and what you want to do with it, to get an exact answer you need to provide more details.
Here is an overview for the actiity life cycle that should help you:
You can extend the default Application class and implement it's onCreate() method to detect when the app is launched. There is no corresponding method for when the app gets closed though.
Do not forget to specify it in the Manifest file.
In Android the application isn't shut down unless the system runs low on memory. You won't get a warning about that, it will just call your Service's onDestroy lifecycle method. If you want to do it when the Activity is visible on screen, use onStart and onStop. If you want to do it when the Activity is resident in memory, use onCreate and onDestroy.

Can user starts an application with screen off?

In my application I check to the server some user state in the onCreate() method of the main activity.
I recently notice that doing so is an issue when I run the app from Eclipse while the phone is asleep (screen off, locked). In this situation, the application waits that the screen get unlocked to call the onStart() method and pursue its way. That makes fail the data update.
Maybe I should put it inside onStart?
Can the user do the same process = start an app with locked screen? I though of Tasker but are there other way?
Edit: All the server updates communication are done off main thread, handled by managing classes and I use volley. So it's not a service and though I will put one later, I have not enough time to do it now. Except if you say it's 2 days work to learn and implement. Can a user start an application like a dev can do it ?
This things that you are doing in an Activity must surely be performed in a Service. Android Service provides you with doing background data processing/syncing.

android activities being launched repeatedly unexpectedly

In my app I have a simple button that launches a second activity, starts a spinner (If that's relevant) and does some http connection work. This second activity can also be launched by a service that runs and listens to a bluetooth connection.
The problem is not happening on my milestone (2.1-update1) phone but on a colleagues phone who is running 2.3 I believe. When they press the button to launch the second activity (Ignoring the service portion completely) it will launch the activity multiple times, when they press back on that second screen they land on another instance of that second screen instead of being back on the first activity.
I mention the service part of this for two reason, the first being that this problem started happening when I implemented the service, and the second being because I had a separate problem where the clients weren't being managed correctly on the service side so that when the second activity was being launched through the service instead of the button I would see exactly this behavior. Since the message was being sent to all clients (There should only be one) I was seeing the service spawn multiple launches of this second activity. But again by pressing the button this service problem which has been fixed shouldn't be responsible.
Now, I have put two things in place to prevent this from happening anymore. I have flagged the second activity as singleTask (android:launchMode="singleTask") and noticed that I had been launching the second activity as startActivityForResult, but wasn't setting or using that when it came back. This wasn't causing any errors or anything, but I changed it to a plain startActivity.
I do not have physical access to the other phone so I can't hook it up to logcat or anything, as it is in another office elsewhere.
The other phone isn't seeing the problem anymore but I am worried that I have hidden the problem rather than really fixing it, and was wondering if anyone could provide some insight?
I've had a problem before where different phones exhibited different symptoms when starting services. Some would restart (kill and start) the service multiple times and others would not. I'm taking a guess that because your friend's phone restarts the service multiple times somehow your activity is getting called each time it restarts.
Try this, can you show notifications in your service? If so do:
startForeground(ID_NOTIFICATION, notification);
This makes the service always run in the foreground and it is less likely to be killed by android.

What do I use to restore my Activity's state when it has been recreated?

I've been looking around at many forum discussions, but none of them answers properly how to handle runtime changes that forces the actual activity to restart.
In my case, for example, my activity uses an AsyncTask to show a ProgressBar while fetching data from server. But, if user just rotates the screen, the activity is restarted and repeats the request to server.
If screen rotation is done while the AsyncTask is still in doInBackground(), waiting for server's response, I get a android.view.WindowLeaked error.
I just want to, whenever the screen gets rotated or another interruption occurs, my activity continues doing its job from where it stopped, could that be this hard?
onSaveInsanceState() is recommended? How could I save a partially received JSON in a Bundle? Or maybe I should use onRetainNonConfigurationInstance()...
Will send a bottle of Brazilian's drink "caipirinha" for the good soul that helps me...
You need to use a different architecture.
Move the background operation from the AsyncTask into a Service. A service runs in the background independent of any Activity, and does not get restarted when you change the orientation of the device.
The background Service can communicate with the foreground Activity via broadcasts. Within the service, you can send broadcasts w/ progress info using sendBroadcast(). You can receive the broadcasts in the Activity using a BroadcastReceiver.
EDIT: For less drastic approaches that may be suitable depending on your situation, see:
http://developer.android.com/guide/topics/resources/runtime-changes.html. In particular, if you do not use different resources for landscape and portrait, then the second method (handling the configuration change yourself) may work well.
EDIT2: Some additional info here:
Activity restart on rotation Android

If my application goes to background, it still continue working? (sending/getting data from internet)

i am working on an application that send and get data from internet each 5 min
if i press home key and my app goes to background... it will still continue sending/getting data from internet? or i have to do something special?
thanks
"If an activity is completely obscured by another activity, it is stopped. It still retains all state and member information, however, it is no longer visible to the user so its window is hidden and it will often be killed by the system when memory is needed elsewhere. If an activity is paused or stopped, the system can drop the activity from memory by either asking it to finish, or simply killing its process. When it is displayed again to the user, it must be completely restarted and restored to its previous state."
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
No. Activities shouldn't be depended on to process tasks in the background.
The following link illustrates the fundamentals of different Android components and what they do, i.e. the "parts" of an app.
You should be using a Service for background processing.
From what you're saying, I'd suggest an IntentService fired by an Alarm.
Application Fundamentals

Categories

Resources