I have a service bound to an activity. I defined an interface that is implemented by the activity. In the service I have an object of the interface that implements the activity, i give memory to this object when I call the method that returns the binder.
The service implements socket.io when I receive a message from the server, I call the interface method to update data in the activity.
My question is, am I using bad practices? Should I implement a LocalBroadcastReceiver to communicate with the activity instead of using the interface?
what do you suggest me?
Short answer is yes it is really a bad practice.
Long answer, even though you reference your activity over an interface it's still the same object in the memory. So let's say you have long running operation on your service then when the activity is recreated after a rotation or any kind of configuration change your old reference will be kept in the Service and it will be leaked.
So since your question is too generic I can just list the alternative methods, you can look through all of them and apply whichever fits on your style.
EventBus (Publish/Subscribe pattern, the easiest solution)
Dependency Injection (Use Dagger or similar to inject your model on
both Activity and Service
BroadcastReceiver
Messenger
Related
I have a singleton class with the "block/allow logic" for my VPN tunnel. Packets sent into the tunnel are not emitted, applications are allowed to bypass based on an allowance list, therefore it can behave as a simple implementation of a firewall.
What I want to do is, when I change the Set<String> of blocked application packagenames, I would like the service thread to run vpnservice.builder.establish() again, using this blocked application set.
An obvious choice for this - in case an "ordinary" foreground service if the service extends LifecycleService, as shown here. However, my service has to extend android.net.VpnService, which does not implement LifecycleOwner. A possible implementation (with some modifications needed) is shown here.
My questions are:
Is there a better, cleaner, more elegant way for my VPN service to observe changes in my blockedPackageName Collection, in my singleton class?
If there is not another way, will implementing LifecycleOwner work in the way I expect it (how I described it, basically)?
If(2), is it enough to add lifecycle.handleLifecycleEvent(Lifecycle.Event.XXXX); in my service's onCreate and onDestroy methods (see below)? Do these do anything apart from preventing memory leaks?
//MyVpnService class
#Override
public void onDestroy() {
Log.i(TAG, "Destroyed.");
stopVpn();
//what is the purpose of this line for my goals?
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
}
P.S.: I read the official documentation with regards to Lifecycle components, but I could not find enough code examples for my cases to make the matter more clear.
The best solution I find was to send a broadcast with a custom intent from the singleton class, and signing up a broadcast receiver for this intent in the vpnservice class on start.
For sending a broadcast from any class, you need context - lucky for me, I already needed context in my singleton, for which context.getApplicationContext() works fine without leaking.
I have a class that extends service and the service basically fetches data from the cloud and lists ot in a listview..am getting an error when i try to use "findviewById" method to get the listview because the class doesn't extend Activity.does anyone know how i should go about it.
Your service cannot modify the UI directly. In fact, there may not be a UI at all, as the user may have pressed BACK and destroyed the activity while the network I/O is going on.
Instead, you need to send a message from the service to the activity to let the activity know, if it exists, that there is new data. For this, you can use:
LocalBroadcastManager from the Android Support package, or
a third-party message bus implementation, like Square's Otto, or
a Messenger tied to a Handler
etc.
Hi There in my opinion better to use the AsncTask in that you have to write the backend downloading data part in doinBackground method and setting the data to the list view in onPostexcute.
Better have a look into the asynctask
http://developer.android.com/reference/android/os/AsyncTask.html
mean while try to bind a service and make communication from service to activity for this have a look into how to bind a service.
for binding a service
http://developer.android.com/guide/components/bound-services.html
I have an application that keeps some complex data in memory between activities.
As for now I use a Singleton class that use SharedPreferences in getters and setters.
What I want: As long as my application is live and showing in the recent apps, I want a class to never get released or find a way to achieve this another way without consequences.
So I was wondering, is a better way available to me?
Would a Service be better?
If so, should I start and/or bind it?
If you go with a service, you wouldn't bind it as unbinding could cause it to stop.
You could create a static object and create it in a custom Application class. So for as long as your application is alive the object is held by a strong reference.
Or a combination, use a singleton class but let the application class store the reference to prevent garbagecollection(GC)
after chat:
a service running in its own process should be the most persistent thing you could build. However you need to communicate with the service via AIDL, a cross-process bridge, which draws performance if the communication is high-speed.
I would like to bind and connect a service but not within an android activity. Is there a class witch could be extended to have a context necessary for binding?
What i am trying to do is to provid a simple java library using an android service. My library does not use a UI. I only need to bind and connect my service inside a class witch necessary have application context necessary to the binding
Thanks
You can get the context from your application class. Derive your own class from Application, and give it a static getApplication method. You can use that for creating services.
Note that without an Activity, binding to a service may be a little hard - if, for example, you're in a BroadcastReceiver, it's not going to be alive long enough for you to receive the callback after the service has been bound.
Simply create an application without default activity. Then extend base Service class. And do not forget to describe it in the manifest file.
Service has its own context.
I have an API Object that I made, and I would like to share it between a running Service and various Activities in my app, almost like if I was to make the class static. How could I go about sharing the created object between the two?
You may find the following helpful.
Binding a Service to an android.app.Activity vs Binding it to an android.app.Application
Android Service interacting with multiple activities
Alternatives for Pushing data from an Android Service to an Activity
I figured out the best way to do this is to have a class that holds all the information that you want, and to use that class through each activity and service.