I am sending some data from my activity to a server. I keep it running in background using:
public void onBackPressed() {
moveTaskToBack (true);
}
But if the data is not being send for say about 10min because of some network problem. After recovering from n/w problem it doesnt continue to send.
Why is it so? Does the activity stops after sometime if it has nothing to do?
You can simply start a Service that will run in background and
send your data to server. If you call that in main thread of the activity it may hang you activity and could not process it because activity has a life cycle. It may end UP!
start a background service and perform all the operation in it. :)
Check out the documentation. This method just moves your activity to the back of the activity stack, it is still being paused, and so - eligible for finalization by the OS. Your activity is probably being destroyed.
If you want a certain process to keep running while your activity is paused, either use a service, like Raghunandan suggested, or start an AsyncTask if you need to update the UI after your data sending has completed.
Related
I have 2 activities which are using the same Android task - i.e. they will use the same back stack.
Let's call A the first activity in the back stack, and B the second activity in the back stack.
case 1: A is notified that it goes in the background when A was in the foreground and then B comes in the foreground (for any reason, like because it received an external intent).
case 2: A is notified that it goes in the background when A was in the foreground but another application was started in the foreground.
Question: How does my app differentiate between those 2 cases? Is there a way to know if the transition A in foreground -> A in background keeps the current task displayed on the screen?
Basically, I need to get an event when the Android task becomes visible or invisible.
If I understand you correctly, your Activity A would do something different if Activity B doesn't get activated after A was paused.
First of all, it's not a good idea to let an activity do something when it's not visible anymore. As we see in the Android lifecycle, it could get stopped:
I would put your background code into a service. This service gets notified whenever Activity A or B gets paused or resumed. There you could add a little timeout which has to pass till you start your logic.
If you do that, that would happen:
Case 1:
Activity A goes into background and sends a message in the onPause handler to your service. Service starts its timeout timer. Activity B gets started and sends a message in it's onResume handler to the service.
Now the services knows it's still the same activity and acts accordingly.
Case 2:
Activity A goes into background and sends the message. The service starts its timeout timer. It timeouts (I think 200ms would be enough) and now your service knows the task isn't active anymore and acts accordingly.
Use log or Toast in activity life cycle to display message
Keep a static flag in Activity B. set it on resume and unset it on pause.
Override onPostResume
#Override
protected void onPostResume() {
//Your code here
super.onPostResume();
}
Let's assume I have 2 activities: Activity 1, Activity 2. I am starting Activity 2 from Activity 1. Activity 2 - is activity with image and progress bar to display the progress of executing some background task in it which is started in service.
When I try to press hardware Back button from Activity 2 it brings me back to Activity 1, so I can start Activity 2 again even if there is service still running.
So the question is such: How can I prevent such behaviour. I need to start Activity 2 only 1 time and not exit from it while the work is not finished?? And another case is that I can stop my application from Task manager, but service will be working and after that I can run application again - with new service, while old will be still running? What mechanisms are there to prevent such behaviour? Thanks.
You can bind to a local service from your Activity class when it is starting up. Once bound, your Activity can call any public methods declared by that service. This would allow your Activity to bind to the service, then check to see if the service is currently doing any work. You might make a method like isRunning() or similar. If the service is not currently doing any work, you might want to start a new job. If it is already executing some task, you could then display the current progress of that task.
You should read the Local Service Sample article on the Android developer site to get an idea how to do this.
I am writing an Android app (ICS) for a tablet. The user moves from Activity A to Activity B to Activity C with the touch of a button. I want to return from Activity C to Activity A after 10 seconds. Is there some way to count to 10 without locking up Activity C?
I've succeeded with an asyncTask but if I startActivity(A) in the onPostExecute() it feels like I'm violating the guideline that an asyncTask should not mess with the UI. I've tried get() but that does lock up Activity C while it's waiting for the 10 seconds to pass.
Thanks in advance!
Assuming you have any View instance in your activity, you can use View.postDelayed() to post runnable with a given delay. In this runnable you can call Activity.finish(). You should also use View.removeCallbacks() to remove your callback in onDestroy(), to avoid your callback being called after user already navigated back from your activity.
Using AsyncTask just to count some time is just an overkill (unless you want to use AsyncTask to actually do some useful, background work). The Looper and Handler classes provide everything you need to execute any code on UI thread after a given delay. The View methods mentioned above are just convenience methods exposing the Handler functionality.
Using AsyncTask works fine as you describe. From Android Documentation:
onPostExecute(Result), invoked on the UI thread after the background computation finishes.
Since it is invoked on UI thread you should be fine.
Documentation
You can use a alarm manager for that. Set it to send a broadcast 10 seconds starting from activity a and implement a base activity for activity a b and c to receive the broadcast, after receiving the broadcast just end the current activity and start activity a with a new flag. If the current instance is activity a then ignore if not start activity a. Something like that.
As for the idle part you can update the alarm manager on every action, upon entering activity etc.
The advantage of this implementation is that you dont have to go through the hassle of having to worry about context leaks, persisting timers across activities and such. and can make use of what is already there. You can also consider using a service though.
If not you can just use the shared preference store the time to time out and check or update against it for the actions.. A simpler implementation.
Good luck.
I'm trying to kill 2 activities on the onclick of a button. The current activity and the previous activity. Using their pids. I'm just able to kill one activity. Why does this happen?
public void onClick(View v) {
android.os.Process.killProcess(pidofmain);
android.os.Process.killProcess(android.os.Process.myPid());
}
If I see in my logcat, The activity with pid "pidofmain" is getting killed whereas the current activity is not getting killed.
"pidofmain" is an integer i received from the previous activity using an intent.
Leave process killing to the OS. This is bad for any kind of program in a timesharing OS. If you want to conserve memory or something like that, let the OS handle it.
Also you can't really know if the process was correctly killed because well, if it is you wouldn't know, and if it doesn't you were not supposed to do it.
What do you want to do this for?
A much better way to do this is to call finish() for the current activity. You can also signal the previous activity to finish if it calls the current activity using startActivityForResult(Intent). The current activity would call setResult(int) before calling finish() to send a return code back to the previous activity. The previous activity can test the return code in onActivityResult(int, int, Intent) and also call finish() based on the result code.
Killing processes should be left to the OS. Once the activities finish, the will kill it off if it needs the resources. Otherwise it can let it around, which might help speed up a relaunch of your app if the user wants to run it again.
This isn't a definitive answer, but more like some thoughts that I have but it's too late for my to fire up Eclipse and prototype them. If it doesn't help you let me know and I'll try to look into it deeper tomorrow night.
A few thoughts (I hope they help):
1) Android apps really are single-threaded, and your main activity controls all the dispatch events (including events to what I assume to be a second thread that you created). If you kill the main activity, I'm pretty sure that your application would terminate execution immediately following your first call to android.os.Process.killProcess(pidofmain), and you'd never make it to your second call because you would have killed your entire application. Again, this is assuming by the variable name pidofmain that you are killing the main UI thread and not just an activity called main.
2) I'm a little curious also about where you got pidofmain? It sounds like you have three activities total, and in the first activity you get it's process id and send it to the second activity in an intent bundle, which also gets passed along to a third activity (which is the place where you're trying to kill this whole thing)? If that is the case, and you're trying to kill the currently running activity, the table in the documentation here leads me to believe that you can't just kill an activity that's in the resumed state using the same method. Official Android Docs for Activity You might want to try calling the finish() method for your currently running activity.
What exactly do you see in logcat? And what happens in the UI? Does the visible activity continue to run, but the other activity has been removed from the backstack?
I'm taking a stab at a large program with a background Service and I'm implementing a (rather poorly thought out) Message handling procedure using basic Handler objects. The application has a main menu with buttons which start 6 different activities.
Problem is this: if i start a worker thread which kicks off a query to the database and retrieves some data, and I close the Activity that started the aforementioned worker thread, the Handler in the Activity still tries to run and show a dialog, even though the Activity that created it is now finished (or not in focus). How can I tell whether the current Activity is in focus before committing any (UI) changes?
I ended up solving the issue by simply putting the 'showDialog()' call in a try statement, but i'd like a more sophisticated solution, as this just seems like the wrong way to do things.
Use sendBroadcast(), with the Activity registering a BroadcastReceiver for the broadcast via registerReceiver() in onResume() and unregistering it in onPause(). Then, it will only process the event if it is in the foreground.
Put some flag in onPause() method of activity that starts the thread to indicate that it is not foreground anymore. In onStart() reverse the flag.
When it is a time to display dialog, check this flag and only show dialog if activity is running.