How to handle service stopped in background - android

My ex colleague developed a service which plays music in background. However if user wants to exit from program then application calls below code to stop service. Service stops but i cannot handle it while overriding onDestroy method
Activity realAct = context.getParent();
if (realAct == null) {
realAct = context;
}
ContextWrapper cw = new ContextWrapper(realAct);
cw.stopService(new Intent(cw, MyPlayerService.class));
edit:
Briefly, Activity Main starts Activity Sub then Activity Sub starts Service. Then i press back button so Activity Sub finishes. When i am in Activity Main I call above stopservice code. So onDestroy method of Service is not called

Try again to use method like that in code of your service :
#Override
public void onDestroy()
{
super.onDestroy();
//your code
}
It has to work !

Are you trying to stop the service when the user exits from application?
onDestroy is called when system needs to kill activities due to insufficient resources. Just because you pressed back on your app doesn't mean onDestroy gets called immediately.
But if you want to force close your app to have it automatically invoke onDestroy, call
finish()
on wherever you are exiting your application from.
If you want to invoke onDestroy upon user pressing back button to exit, Override onBackPressed() and invoke finish() from there.
But really, this is an antipattern so I'd recommend using onPause() instead.
Edit Upon OP Edit:
I think we need to have more details on how you are instantiating the service but here are some additional thoughts:
Have you overridden onDestroy properly and calling the super method?
If this is the case, the only other possibility I can think of is that you still have ServiceConnection objects bound to the service with BIND_AUTO_CREATE set. Until all of these bindings are removed, service will not get destroyed.
So make sure to do both:
unbindService(conn);
stopService(intent);

Related

activity finishes itself but onDestroy() call for this activity happen so late

I found a bug in our code that we are launching the activity(let's call this as SCREEN_ACTIVITY) by
Intent intent = new Intent(SharedIntents.INTENT_SCREEN);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
Android documentation : When using FLAG_ACTIVITY_NEW_TASK, if a task is already running for the activity you are now starting, then a new activity will not be started; instead, the current task will simply be brought to the front of the screen with the state it was last in.
So everything works fine in most of the case.
That screen activity will call finish() when user click something. Also this screen activity will get launch or create by incoming event from the service.
6053 I/ScreenActivity(15395): onCreate
6682 E/ScreenActivity(15395): finish() Activity
6832 I/ScreenActivity(15395): onDestroy
7284 I/ScreenActivity(15395): onCreate
7911 E/ScreenActivity(15395): finish() Activity
8063 I/ScreenActivity(15395): onDestroy
10555 I/ScreenActivity(15395): onCreate
13413 E/ScreenActivity(15395): finish() Activity
13701 I/ScreenActivity(15395): onCreate
13799 I/ScreenActivity(15395): onDestroy
The last one is the issue. ScreenActivity is created and then call finish() itself. But the problem is that onDestroy is being called very late. Before that there is incoming event from the server and calling startActivity() trigger a new ScreenAcitivty onCreate(). The problem is that ScreenManager class keeps flags for that activity created and destroyed.
The flag is set when onCreate() callback and onDestroy() callback.
So for line 10555 and 13701 the ScreenManager set createFlag = true. for line 13799 set createFlag = false.
The event comes after line 13799 will assume that the activity is not created and events are not notified to the activity.
Hope my description for the issue is clear to you.
Is this kind of scenario onStop() and onDestroy() call so late after calling finish() is expected to happen? If yes, i have to think about the solution.
If not, then is there any places to modify?
Thanks a lot.
onDestroy() may or may not be called. You cannot rely on it being called all the time. From the docs:
Note: do not count on this method being called as a place for saving
data! For example, if an activity is editing data in a content
provider, those edits should be committed in either onPause() or
onSaveInstanceState(Bundle), not here. This method is usually
implemented to free resources like threads that are associated with an
activity, so that a destroyed activity does not leave such things
around while the rest of its application is still running. There are
situations where the system will simply kill the activity's hosting
process without calling this method (or any others) in it, so it
should not be used to do things that are intended to remain around
after the process goes away.
If you need to know that your Activity is finishing, a reliable way to know if it is finishing is the isFinishing() method. You can call it in onPause() to find out if this pause will eventually lead to this Activity being destroyed:
#Override
protected void onPause() {
super.onPause();
if (isFinishing()) {
// Here you can be sure the Activity will be destroyed eventually
}
}
use Handler,
new Handler().postDelayed(new Runnable() {
#Override
public void run()
//enter code here for open an Activity
}
},300);
after that, we are getting log should be:
onCreate
onStop
onDestroy
onCreate

Activity onCreate and onResume not called

I am working on an android project. There is a MainActivity and a Service. When user press back key twice in a given time period within MainActivity, I use the following to finish the activity and stop the service.
finish();
int pid = android.os.Process.myPid();
android.os.Process.killProcess(pid);
When I press the app icon to restart the app, MainActivity appears and Service restarts. However, onCreate and onResume in the MainActivity is not called. The first call in the log is onAttach for fragments.
How could that be possible?
You should not "kill" this by design.
Call
finish() and stopService() or stopSelf()
for your Service.
Killing the process may lead into unusual behaviour since the whole app gets restarted. It may be possible that even if the "App" is killed that the view is still in memory.
Check your Mainactivity onPause() and onDestory()
If your onDestory() called then you onCreate() and onResume() Definitely Called
Note: onDestory is a risky one. If the app killed by Android for memory allocation most of the time onDestory won't get called.

Stop an app by calling the lifecycle callbacks

How can I stop my whole App in simple terms? (all activities, services, Threads, etc. simply everything) The life-cycle callbacks (especially onStop() and onDestroy()) should be called.
Google suggests the following possible solution:
kill the process: but this wouldn't call the lifecycle callbacks
and finish(); but this is only for one Activity:
But is it possible to access this method from outside like:
//Getting all activityies, how?
//For each gotten activity
AcitvityName.finish();
or via or via getParent().finish(); ?
This did not help me: Best way to quit android app?
FD
#Override
public void onPause() {
if(isFinishing()){
//code to finish() all activitys threads etc.....
}
super.onPause();
}
in onPause() you can check for isFinishing() and then if it is finishing it goes to onDestroy() so you can execute some code youd like
Use a broadcast receiver to call all your activities and call finish locally in them, invoking the current lifecycle callbacks.
Broadcastreceiver and Paused activity
http://developer.android.com/reference/android/content/BroadcastReceiver.html
Android don't allows user close application directly. You may minimize it to background or directly killing process.
But if you want to call some callbacks and release any resources when user remove your application from screen - you may to do following:
Clearing activity stack in onDestroy method (or if you wish in onBackPressed, onHomePressed). It must calls onDestroy methods in all removing activities so you may release any extended resources in onDestroy method of activity which has links on it.
So when user exit from your application - it will remove his activities and release all resources.

What happens if I startService from onCreate in Activity, finish() the Activity and then start the app again?

I am trying to figure out how Android works when it comes to lifecycle issues.
I have decided to have a long-running Service to hold my TCP-connections and other stuff.
I have one Activity, StartupActivity. That Activity starts a service, and then I press a button to Finish the Activity. I then launch the same app/Activity again, and thus the startService is executed again.
However, I expected the Service to still be alive (there has been no onDestroy called), but the onCreate-method in the Service is still being executed.
Why?
STEP 1: onCreate in StartupActivit is executed:
#Override
protected void onCreate(android.os.Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.startup);
startService(new Intent(StartupActivity.this, SamcomService.class));
registerReceiver(connectionReceiver, new IntentFilter("STARTUP_PROGRESS_MESSAGE"));
registerReceiver(connectionReceiver, new IntentFilter("STARTUP_FINISH"));
final Button button = (Button) findViewById(R.id.buttonExit);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
finish();
}
});
}
STEP 2: I press the button, and Activity.finish() is called (I am returned to the home screen)
STEP 3: I launch the app again, and the onCreate for the Activity is once more executed, thus starting the same Service
Now, when I start the app the second time the Service should be running (how do I check that?). I havent seen the Toast that is displayed when the Service onDestroy is called, and I also see the Notification that the Service creates (and removes onDestroy).
However, the onCreate is executed a second time. Do I now have more than one Service running at the same time?
However, the onCreate is executed a second time. Do I now have more than one Service running at the same time?
No, and I know this is confusing, but the startService() method does not start the service. It will be called in the service everytime you run it. For instance, if the service isn't started, it will start it and then run it. If the service is started, it will just run it. The android documentation says it was designed this way so that the startService() method is the easiest way to communicate with your service.
STEP 2: I press the button, and Activity.finish() is called (I am returned to the home screen)
This depends on if your service is running on the same process as your activity or not. If you have :process = "something" in your service declaration in the manifest, and you did everything else perfectly, the service is in another process and there are only three situiations inwhich your service will be destroyed. 1, your activity is destroyed(Almost guaranteed not to happen as your process has its activities active priority), 2, There is EXTREMELY low memory, 3 the service calls selfStop().
Since finish() does not destroy your app(Android keeps it around in memory encase the user comes back to it), your service is either just paused(If it was in the same process) or still running(If it was in a different process). Regardless another call to startService() will restart it if it was paused and run the service's startService method. You only ever have one of your services around.

how to stop or finish activity from called service?

In my app I am required to Stop the activity(MyAct.java) when a service(BackgroundService.java) is called, and further i wish to continue this service(BackgroundService.java).please help?
Implement a started service, call startService(Intent service) in your activity(for instance, a button pressed) then call finish() immediately in your activity.
Check out here to see how to create a long running background service, even without need a activity to start the service.

Categories

Resources