Android binding service - android

I have one service and two activities. I from one Activity go to another, and in the onStop method, do unbindService.
When I came in the second Activivity the service destroyed.
When the second activity calls the bindservice, a new service is created.
How to make so that the service is not destroyed?

If you want that service should not stop when migrating to next activtiy,then you should use IntentService instead of Service.
InetntService don't have any UI,so it will contiously runs in the background without user interaction and when it finishes then you have to store its data somewhere (or you can use the broadcast reciver )and populate that data in the next actvity if you need.

Related

Starting an activity from a background service and wait for it to be created

I have a Background service that sometimes needs to start an activity. I would like to wait for this activity to be created (that is OnCreate() has exited).
Once the activity has been created it has registered for receiving messages.
I'd like the background service to send a message once the activity is created.
How can I do the waiting without blocking?
Well I ended up with using an IOC container to share an object instance between the the two contexts. This object would contain an AsyncAutoResetEvent for the activity to set and the service to await.

Android: Service startService or Bind service

I have a service that is used by the main activity to do some background job and it's started using binding and unbinding.
In this way, when the activity start the service start and stop when the activity call unbind, this work well.
Now I need to have a CheckBoxpreference that once true will start the service and it must run in background despite the main activity will be close.
What is the best way to get this result? do I have to work on startservice/stopservice from preferences or I have to don't unbind from main activity when the preference is true?
if I start the service from the preference when already started from the binding of main activity, this will be multiple instance of same service ?
Thank you
Use a OnSharedPreferenceChangeListener so you'll get updates when the checkbox changes from selected to unselected (and vice versa).
You can use both the start/stopService mechanism and the bind/unbind mechanism at the same time. The service will start if either startService is called or if the service is bound, it will stop when stopService is called AND no activities are bound anymore.
I think this post will answer your question regarding services that have already been started.

Stopping and starting a Service based on application state

I have a Service which tracks the location of the user. Currently, the Service boots when the application starts and stops when the application terminates. Unfortunately, if users keep the application in the background, the Service never stops and drains battery.
I would like the Service to stop when my application is not in the foreground. I was hoping the Application class would let me Override onPause and onResume handlers, but it does not have them. Is there another way I can accomplish this?
I haven't tested this yet, but it looks like if you use Context#bindService() (instead of Context#startService()), the service should stop when no more activities are bound to it. (see Service lifecycle).
Then use onPause()/onResume() in each activity to bind/unbind from the service.
Alternatively, you could add a pair of methods on your service which tell it to start/stop listening for location updates and call it from each activity's onResume()/onPause(). The service would still be running, but the location updates wouldn't be draining the battery.
Reading all the above answers I would suggest Simply add a boolean global flag for each activity & put it in your onResume & onPause & also while launching an Activity Something like this
public void onPause()
{
super.onPause();
activity1IsResumed = true;
}
&same for onResume
& similarly when launching a new Activity
startActivityForResult(myintent ,0);
activity2IsResumed = true;
activity1IsResumed = false;
then in your Service simply check
if(activity1IsResumed || activity2IsResumed || activity3IsResumed)
{
//your logic
}
else
{
//another logic
//or dont run location tracker
}
& you are done!
You should override the onPause and onResume methods on your Activity. If you have multiple activities you may want to have a common base class for them and put the start/stop logic into the base class.
I have not tried this approach but I think you can override the home key of android device by using KeyEvent.KEYCODE_HOME and you can use stopService(Intent) to stop your service and when again application resumes, you can write startService(Intent) in the onResume() method of your Activity.
This way I think your service will only stop when user explicitly presses home button to take application in the background and not when he switches from one activity to another.
What I would suggest is overriding the onPause/onReume methods as others have said. Without knowing more about the flow of your application and interactions between Activities, I can't give much more information beyond guesswork.
If your Activities are persistent, however, my recommendation would be to utilize the Intents better when switching between Activities.
For instance, each Activity should have a boolean "transition" flag. So, when you move from one Activity to the next, you set up an Intent extra:
intent.putExtra("transition",true);
Followed in the receiving Activity by: (in onCreate)
intent.getBooleanExtra("transition",false);
This way, for each Activity that launches, you can know whether it has come from another Activity, or if it has been launched from a home screen launcher. Thus, if it gets a true transition, then onPause should NOT stop the service--that means you will be returning to the previous Activity after it returns. If it receives no "transition" extra, or a false transition, then you can safely assume there is no Activity underneath it waiting to take over for the current one.
On the first Activity, you will simply need to stop the service if you are switching to another Activity, which you should be able to figure out programmatically if one Activity is started from another.
It sounds like the real problem is how to only stop the service when you go to an activity that isn't one of your own? One way would be to in your onPause method to stop the activity. Do this for all your activities. Then override your startActivity method. And in here do a conditional test to confirm that you are purposefully navigating to one of your own. If your are set a flag to true.
Now go back to your on pause overridden method. And only stop your service if the flag is not equal to true. Set the flag to false.
All events that navigate away will close your service. Navigating to your own will leave it intact.
Do the overriding in a base class that all your activities extend.
Writeen in my andolroid. Will post ezaple later.
Try using the Bound Services technique to accomplish this.
Bound Services | Android Developers
You can use bound services in a way such that the service will stop when no activities are bound to it. This way, when the app is not in the foreground, the service will not be running. When the user brings the app back to the foreground, the Activity will bind to the service and the service will resume.
Create methods registerActivity() and unRegisterActivity() in your Application object and implement first method in all you acts onResume() and second in acts onPause().
First method add activity to List<Activity> instance in your app object, unRegisterActivity() checks size of list in every call if==0 stopService();.

how to send data to multiple activities in controlled manner in Android?

I am working on an android application, where there are 4 activities. Activity1 is main activity and there are different buttons on that activity which can open other activities. Other 3 activities can also open each other. There is a thread running in Activity1 which returns some counter. I need to show that counter on all activities.
At an specific time, the thread doesn't know which activity is at top. What is the right way to control this scenario, such that thread output should update on all activities, no matter which one is at top?
I would have that counter on a Service and I would send updates through broadcast intent.
Each Activity will register a listener to that intent on the onStart method and unregister it on onPause. This way the update will reach only the Activity that is on screen.

Android Service interacting with multiple activities

I'm trying to refactor/redesign an Android app. Currently, I've one UI activity (Activity 1) that creates a DataThread. This thread is responsible for network I/O and interacts (provides data) with the UI activity via a handler.
Now, I want to add another activity (a new UI screen with Video) - Activity 2. Activity 1 is still the main activity. Activity 2 will be invoked when the user clicks a button on Activity 1. Activity 2's data also comes from the DataThread.
My idea is to put the logic of my DataThread inside an Android Service (DataService). My question is - can more than on activity bind to my DataService at the same time? Is there a way to tell the service to provide data to a specific activity only?
Any other ideas are welcome?
Thanks in advance.
Definitely more than one activity can bind to your service. You will get an onBind() for each one that binds. Your service would then ideally handle the logic of interacting with multiple activities by identifying them using an ID or the intent (with your own IDs for each activities as extras) from onBind() in your service. You could then have the Service spawn off a background thread for each activity that binded to it.
I usually bind my service from the Application class and have some kind of controller class (like a "mediator" I guess...not sure how all these patterns are named) scoped in the application that handles communications between services and whatever the active Activity is.
This would involve writing your own Application class and telling the Manifest to use this one. I went into more detail on this process in a previous thread:
More efficient way of updating UI from Service than intents?
You could keep track of the "currently active" Activity by sending the Application class a reference to itself in onResume (also explained in the example above). This can be accomplished by deriving your Activities from a common base class that has a way of getting your Application class (casting from getApplicationContext), and in this base class' onResume, send a ref of itself to the application. Then, you can register activities by name with your DataServiceController, for example, and send messages to the current Activity only if it's registered with the Controller to receive them.

Categories

Resources