I got a situation where i have two APPS for simplicity keep it as APP1 and APP2, i am passing an object remoteCallback as CALLBACK from APP1 to APP2 for future use.
where based on result APP2 will instantiate a method updateStatus(String msg) using a object remoteCallback, Everything is working fine but, when i close the APP1 and clears the memory, APP2 is unable to call the method i know what causes this problem i want to know is there any way to make the object(remoteCallback) live even the APP1 closed.
Thanks in advance.
I'd use an unbound Service here. Unbound services make that even if one of your apps close, if the conditions permit it, it will still be running in the background. If you used a bound Service, it would stop with your app if your app stopped.
This differs from an AsyncTask or a Thread, because even if they run in the background, there's a big change of being killed if Android needs more memory or is in lack of resources.
This introduce, however, a new responsibility for you: You'll have to make sure you use startService() or stopService() accordingly within your app and don't leave your Service running indefinitely.
This seems to be a good example about how it works, but you might find lots of documentation about unbound Services
There is no way we cant stop an app from destroy so instead of passing an callback to get details use BROADCAST RECEIVER.
This is the solution i adapted to this situation.
"I want to know is there any way to make the object(remoteCallback) live even the APP1 closed."
PendingIntent ?...
Its the same mechanism used on notifications.
You can start the background service and the store the object which you want to live object after the app is closing
you can declare the public static data member and you use the whole application
Related
I have an Android Library with a service, which I implemented using AIDL. I want a single instance, cross application to be used with other apps. So I have a base app with the service and I managed to make the library for other apps to use the same instance.
My problem comes when I close all apps using the service, because for every app, the on destroy unbinds from the service, but the service is still running.
Also, I'm only using the service by binding, not by startService().
I checked through android studio that the service is running after closing the apps, and the counter I have on the service for each bind/unbind call is 0!. I increment the counter when there is a call to bind, and decrease for calls to unbind. My only way to make the service stop is by opening the base app, which has the service defined and closing it.
Edit: Also noticed that onBind is being called only once, even for other apps that are binding, but the reference for all those apps is still the same service, they share the same information and only one Service is shown in the android studio.
Edit: I've also observed that if one of the apps using the service is the base app, if I close it, the service dies and another one is started, the other apps don't notice the change, they keep using the service as if nothing happened, which is understandable because it's a remote service.
What is happening and what can I do about it?
For the two points being questioned:
I was able to verify what CommonsWare said that the process in which the service is run is still up, but the service itself is not. At first I had a thread running in the service after every app unbound, but after making sure it wasn't up in the end made the service be destroyed.
The second issue, regarding the service being destroyed while still bound with other activities was solved by seeing this link which describes a bug in android that kills services when it shouldn't. My case was simply solved by making my service run in the foreground, which I didn't know was possible.
After some tests I verified the service is still intact as long as any app is bound with it, and that the service indeed is destroyed correctly after no more app is bound.
I have an Android foreground service that contains a map of session (key, session). In my activities, I receive a key and I want to get the session from the service. So I bind each of my activities to the service and I can ask the service to get my session with my key. But doing this means that I have to wait for onServiceConnected() to get the session.
Is it a good idea to bind the service once in my application class and put my service in a static variable, then all my activities can access the service directly in their onCreate() instead of waiting for the call of onServiceConnected()? But is it sure that my static variable will always be there? Do you know if Android can delete that static variable if it needs resources? I guess the application instance is never deleted, am I right? So it could be a good idea to keep my service in a static variable. What do you think?
What you are trying to do sounds like a dirty implementation of some sort of dispatcher from React, I have being tempt to do it my self, but haven't because of lack of time. Please let us know your results.
I would suggest to use a Messager, the doc have information about it, so no need for static https://developer.android.com/guide/components/bound-services.html?hl=en-419
And yes, Android OS can clean anything, it can kill the service, it can null the variables. Most of the time this doesn't happen because it will be done only to prioritize the foreground app. So if a user opens 10 apps and your is on backgound it probably will. Which seems ok to me. From time to tome I have also experienced variables become null in a Fragment, but then I reduced the variable scope and that fix it.
Also if you are considering this, try with EventBus library or by using ReactJava, maybe Realm ORM or even Firebase could help you.
You can bind to the Service in your Application class. The Application instance is basically a singleton and will live as long as the OS process hosting your app is alive. At some point, Android will kill the OS process hosting your app, and then all your app components will go away (Application instance, Service, Activity instances, etc.). If the user returns to your app, Android will create a new OS process, instantiate a new Application instance and then instantiate your app components as needed.
Application itself doesn't have a lifecycle as other Android components, so if you call bindService() during its onCreate() callback, there is no guaranteed point to call unbindService(), which may lead to memory leaks and unpredictable states. Others have also pointed that here.
Instead, you could start your service in the foreground (displaying a notification like "Remote Desktop Manager is running"), which should keep your app alive, and make the map<key, session> a static variable in your Application. In this way, Activities can retrieve sessions without the connection delay. Just don't forget to stop the service by either calling stopService(Intent intent) or stopSelf() when all sessions get closed.
By the way, it should work even considering background restrictions of Android O.
In android how to make sure that the service that I have in the application will get called only through an activity that is within the app.
(In other words I want to limit the service to get played by only a certain activity & not even by other activities within that app)
I tried studying Intent-filters but got a bit confused.
Can someone please suggest, if possible with an example?
Thank You
Use Context.startService(Intent service) to start the service from your activity.
Despite the name it doesnt only start the service. If the service is running already, it just calls it.
From the service perspective, the service will then call its onStartCommand(...) method.
Only an activity within the same application can call/start a service this way.
If you set exported="false" in your <service .. /> element of AndroidManifest.xml, the service cannot be called by activities outside your own app.
I know of no way to limit access to any particular activity within the app, but this seems a less pressing concern. Supposedly you can trust your own code?
I need an advice for my latest app. It will show the user the latest subtitles released, and it will give him a notification in case new subtitles of his favourite series have been released; what should I use to achieve this?
I was thinking to create and run a service which will include a
timer.scheduleAtFixedRate(new TimerTask() {...
but at the same time I really don't know how to make it interact with my app (if the app is opened I don't need any notification but I need to update the GUI).
I could use a thread but I'd like it to run it even after the main activity has been killed...
or I could use a AsyncTask so it would be easier to deal with the Application GUI.
Which solution should I use? I was thinking I should simply use a service (the first solution), but I'm not too sure about it, and furthermore I don't know if there is any way to make a service communicate with an activity periodically...
Thanks for your help.
A service communicating with an activity is called bound service, that's what you should use IMO.
However, you say that when the activity dies, the service should keep running. But if the service is bound to your activity and the activity is dies, the service dies too.
I suggest you to read here about it.
Check and see if you can bind a service to an activity, and when it dies, unbind and let the service continue to run independently.
If you can't, the activity could unbind itself, then start the service independently (with startService rather than bindService).
if you are showing notifications, why not use C2DM messages for communicating with the app. The only thing would be that there would be popups shown to the user even if your app is not running. No need to use threads/services.
I have a Networking service that i want to use as a Service. It's a local Service since it's not valid anymore once the application process is dead and no Other applications need to access it.(or should...).
I was pondering if to use the IBinder interface with local reference to the class and decided not to, for the moment.
I have the following issues:
if the service dies, and i know it can during request processing, it's an issue for me, first i've seen it, the process wont die until the net request returns (then the thread dies gracefully), unless kill -9 is used on the process... then i'm not sure what android does with the connections. I'm not sure what's the approach i should take here.(it will be true though even if this was a local thread and not a service...)
if i want the service to listen on a callback and call it once the network processing is done, i'm in a problem, no instances can be passed on using Intents. So i need some other solutions, all the ones i though of sounds bad to me: A. use IBinder to get instance of the network service class then i can call one of it's methods and pass on an instance, this will work since they all run in the same process, BUT requires me to use Async way to get a Network instance which is not so suitable for me. B. Use static member in the Service i can access, then what to i need the service for ? C. use intent to send parameters only to the service, the service will compose a Request out of it and put it in the queue, then once done will send a response using intent which will encapsulate the response (which might be long!) and will also contain the name of the calling class as a string so all the Receivers will know if it's for them or not - BIG overhead of encapsulating data in Intent and search in all the receivers for the right one to get the response.
I don't want to use the service as a local running simple thread since i'm afraid if i'll run it in the root activity i will have to use static container so it will be visible in each activity and if the root will be destroyed for some reason it will take all the service with it, even if i start new task and the process is still alive...
Anyone got some nice ideas on how to approach this thing ?
Eventually i gave up on the service.
The reason to not use the service But to extend Application object and keep the networking class as a member of that Application object, it is started when the application is created, before any activity is created,and it is shut down before the application draws it's last breath. I know application onTerminate might not be called at all times, but if someone will call kill -9 or equivalent on my Application and the process will die killing the application with it, i'm all set as my Service will be destroyed anyway.
The reasons i gave up a service were:
i have a way to keep a worker thread running during the application life cycle.
Since i have and for future planning will have only one application it will still work in the future.
Since It's not connected and started with any specific Activity it wont be affected by their death or by their creations.
it has a context that will last through the lifecycle of the application so i CAN use it to broadcast events using intents.
when the application dies my service dies with it. unless kill -9 and then the system will kill all threads related to the application, mine included, so i'm still good.
Every activity can use getApplication() and cast to my Application object and get the service.
So no need to use binding and complicate my code with it, no need to think of how to start or end the service, if i'd made a service most chances i'll be starting it from the Application anyway (or the root activity), so i think for me and my app this is the best option.