onUnbind not being called when binding the activity to a running service - android

I have this activity that starts and binds to a service:
#Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(context, SoundService.class);
context.startService(intent);
context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
and I unbind by:
#Override
protected void onStop() {
context.unbindService(serviceConnection);
super.onStop();
}
The service keeps running even after closing the activity. Look at this scenario:
Activity starts the service and binds to it
Activity gets killed, the service keeps running, onUnbind() is called
Activity starts again, and binds to the running service
Activity gets killed, onUnbind() is not called :(
Why is the onUnbind() not being called?

return true from onUnbind, next time if you call bindService again not only onRebind will be called but also when the last clients unbinds also onUnbind will be called by the system

How did you start the service ? Please paste that code.
Service will only be stopped after you called unbindService() IF there are no other clients connected to this service AND the service was started with bind call with AUTO_CREATE. If the service was started with startService() then the service will not be stopped until the service calls stopSelf() or android terminates it to free memory

Related

Destroying a service as soon as the app is killed

I need to create a service that will run as much as app will be running. I know that the most straightforward solution would be to bind service in my Application class but this class does not have onDestroy onStop or onPause methods so unbinding is not possible... sadly... Other approach is to bind service to my base activity (and other activities will extend that activity) and for example onResume bind and onStop unbind service. But then service will be always recreated... And that is not I want. Is it possible to have continuously running service and destroy it as soon as application closed? Here's the second approach (this code is in my base activity)
protected void onResume() {
super.onResume();
if (service == null && !isBound) {
bindService(new Intent(this, NetworkListenerService.class), mServiceConnection, BIND_AUTO_CREATE);
}
}
#Override
protected void onPause() {
super.onPause();
if (isBound) {
unbindService(mServiceConnection);
isBound = false;
}
}
Set the below attribute in your service tag in the manifest file,
<service android:name="service" android:stopWithTask="true"/>
adding this will call the ondestroy() of the service when the task is removed.

android: how to receive broadcast from service when the app is inactive

When my service is running and I can see my app on the screen, everything works fine. My service sends broadcast messages and I can see them in my "MainActivity". But as soon as I push the home button and my app is no longer in the foreground, it stops. The service is still running but the broadcasts don't arrive at my "dead" or "pausing" app. This is my code:
Main Activity:
onCreate:
Intent intent = new Intent(getApplicationContext(), MainGate_Service.class);
startService(intent);
#Override
protected void onStart() {
super.onStart();
LocalBroadcastManager.getInstance(this).registerReceiver(ServiceReceiver, new IntentFilter("MainGate_ring"));
}
#Override
protected void onStop() {
super.onStop();
LocalBroadcastManager.getInstance(this).unregisterReceiver(ServiceReceiver);
}
private BroadcastReceiver ServiceReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String message = intent.getStringExtra("ServiceMessage");
if(message != null) {
if(alarmActive && message.equals("ring"))
new soundPlayer().execute();
}
setNoti(message);
}
}
Service:
#Override
protected void onHandleIntent(Intent intent) {
ring = rcv_ring();
Intent ServiceIntent = new Intent("MainGate_ring");
ServiceIntent.putExtra("ServiceMessage", ring);
LocalBroadcastManager.getInstance(this).sendBroadcast(ServiceIntent);
}
whenever you press home button onStop gets call and there you are unregister receiver so there is not broadcast receiver who can receive broadcast.
LocalBroadcastManager.getInstance(this).unregisterReceiver(ServiceReceiver);
Remove above line from onStop() or unregister it whenever your service stop.
onStop#LocalBroadcastManager.getInstance(this).unregisterReceiver(ServiceReceiver);
literally unregister receiver. So there is no receiver to receive broadcasted message from service.
The problem is here
#Override
protected void onStop() {
super.onStop();
LocalBroadcastManager.getInstance(this).unregisterReceiver(ServiceReceiver);
}
Activity.onStart() :
Called after onCreate(Bundle) — or after onRestart() when the activity had been stopped, but is now again being displayed to the user. It will be followed by onResume().
Activity.onStop()
Called when you are no longer visible to the user. You will next receive either onRestart(), onDestroy(), or nothing, depending on later user activity.
So as soon as you leave your activity onStop() is called and you unregister your receiver.
Don't put your unregister code in onDestroy() either, because it may or may not be called and the Activity might be killed without calling it.
As suggested by #Naveen Dissanayake you might want to reconsider your logic.
You register your BroadcastReceiver inside activity, so, it will depend on Activity's lifecycle. When you press back button, activity goes into 'stopped' state - methods onPause and onStop is called. Android can also destroy this activity in it is low on resources.
Service, on the other hand, i smeant to be running inndefinetely, even when ui is not ready. If you wanat to receive notifications from Activity, there is two
possible solutions:
- Create, store and manage BroadcastReceiver in Application instance - Application class is still running until your app is destroyed. It seems like you want to play sound when service notify you about some action.
Register BroadcastReceiver in onCreate and unregister in onDestroy in notifications.
- Another solution - use another Service if you want to trigger some action or IntentService, reacting to that broadcast.
I woud consider solution - create some ResponseService, start it along with your MainGate_Service (from Application) and stop it from application too. In that Service register BroadcastReceiver or, add IntentFilter into manifest if you want it to start even when app is not running. In your Activity, bind to that service. Serive will know if some UI is attached (if Activity is bound), and, if it is, will notify activity. If it don't - will do some other things (perhaps, show notification)
If you want to receive Broadcast even if your Activity is in
Background then,
Register in onCreate(...)
#Override
protected void onCreate(Bundle sis) {
super.onCreate(sis);
setContentView(...);
LocalBroadcastManager.getInstance(this).registerReceiver(ServiceReceiver, new IntentFilter("MainGate_ring"));
}
Unregister in onDestroy()
#Override
protected void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this).registerReceiver(ServiceReceiver, new IntentFilter("MainGate_ring"));
}

onDestroy of a service is never called

I add a local service to my MainActivity, in the onResume, I did this
#Override
public void onResume() {
super.onResume()
boolean is_start = isMyServiceRunning(MyService.class)
if (is_start) {
bindMyService()
} else {
startMyService()
bindMyService()
}
}
In onPause I just simply do the "unBindMyService" operation.
Also, I add the Context.BIND_AUTO_CREATE flag to bind the service, the result is very strange.
I can see MyService's "onCreate" and "onBind" with logcat, this goes smoothly
When I switch to another activity or app, The "Unbind" is called, which is correct!
When I "force stop" the service in settings, the "onDestroy" of the Service is called in response, that is OK.
When I remove the app from the "Recent List" of the apps, there are no "onDestroy" of the Service is called, I can explain it as that the service is not terminated. also OK.
What I can't explain is that after 4, I launched my app again, I've noticed that the "onCreate" and "onBind" of the service is called, but without a single "onDestroy" of the Service. Even when "is_start" is true, the Service is created again without an "onDestroy" called.
So what happened between 4 and 5? The service is still alive or is dead?
you need to stop service to call onDestroy.
Use this:
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
stopService(new Intent(this,MyService.class));
}

How to unbind a Service when the Activity Stops?

I'm trying to make a music player. To do that I'm creating a service that manages a MediaPlayer object and plays the songs. But every time I reopen my music application it starts a new Service and keeps playing two songs simultaneously. How can I make my Activity bind to the already running service?
I noticed that when I don't call unbindService (...) in the OnStop() method my application runs OK. But I don't know if its right to not unbind when the activity stops.
I'm binding like that:
#Override
protected void onStart() {
super.onStart();
Intent service = new Intent(this,MyService.class);
bindService(service, mConnection, Context.BIND_AUTO_CREATE);
}
#Override
protected void onStop() {
super.onStop();
if(mBound) {
unbindService(mConnection);
mBound = false;
}
}
You need to check on onStart() that is service running or not. If service is already running, then you need to just bind it. But in your current code you creating service everytime.
You should try to use Service.START_STICKY for checking that service is already running or not. You can see :
Service
, start Sticky or start not sticky
I think it will help you to update your service class.
I could fix it add startService(...) to the OnStart( ) method. I didnt understand why this fixed, but seems that I need to do that. If anyone knows why please add. Thanks for everyone help.
this is how OnStart got:
#Override
protected void onStart() {
super.onStart();
Intent service = new Intent(this,MyService.class);
bindService(service, mConnection, Context.BIND_AUTO_CREATE);
startService(service);
}

unbindService() does not unbind from a service?

I have a service that stores a Messenger as a member variable and returns messenger.getBinder() on onBind(Intent). I am connecting to this service with:
void Bind()
{
Intent intent = new Intent("com.example.RemoteBindingService");
bindService(intent, mServiceConnection,
Context.BIND_AUTO_CREATE); // Context.BIND_AUTO_CREATE
// means
// "start if not started"
mBound = true;
}
Before calling Bind(), sending a Message to the service does nothing. After calling Bind(), sending a Message to the service works correctly. However, I would expect that after calling
void Unbind()
{
if(mBound == true)
{
unbindService(mServiceConnection);
mBound = false;
}
}
that sending a Message to the service would again do nothing. However, this is not the case - the service keeps working. Can anyone explain how to properly disconnect from a service?
I assume you started your Service with startService(), because if it would be a bound Service it would get killed if the last Activity unbounds from the Service.
You can stop it
Inside the Service with stopSelf()
Outside the Service with stopService(Intent)

Categories

Resources