I have an IntentService that handles asynchronous calls to a Drupal Services module. Currently, I have my DrupalXmlRpcService object being initialized every time in onHandleIntent because I was under the impression that the service would be killed after the thread is finished. Should this object be initialized in the constructor of the IntentService object?
If your DrupalXmlRpcService object is expensive to create and you use it often, consider saving a reference in the global Application object, or possibly making it a singleton (make sure it's thread-safe). As for your question, if you send multiple Intents to the same service, handleIntent() might be called multiple times, so you might want to init in the constructor (but if it takes too long that might block the main thread).
Related
I have read Android documentation in which a piece of code is synchronized inside the onCreate method, Sync Adapter.
AFAIK Android only creates one instance of a Service so, can Android call onCreate from different threads at the same time? or is it possible to call a Service method before onCreate has finished (using AIDL)?
The documentation you linked to (regarding creating SyncAdapter in a thread-safe manner) makes no sense. onCreate() of a Service is only ever called on the main thread, so there is no possibility that this isn't thread-safe.
Also, you cannot call any methods using AIDL before the onCreate() completes, because you would first need to bind to the Service, and you can't bind to the Service until onCreate() completes.
I'm trying to connect to a Service using bindService().
I am able to obtain reference to the Service in onServiceConnected() method of ServiceConnection.
My question is if I declare a method say downloadFile() in Service and call it through the Service object from an Activity rather than calling startService() and then calling downloadFile() from onStartCommand(), then what is the difference between the two approaches ?
What is the difference between the two approaches ?
The method you are proposing is a wrong-headed approach, for three reasons:
In Android, Activitys and Services are considered to be app components. A component should be treated as an independent entity whose internal methods are not directly called by other components/classes. Such a component should be started using an Intent and then left to do its own work.
If you don't call startService(), you literally never start the Service. How then would you call a method defined inside it ? And manually creating instances of classes that are app components is frowned upon in Android. You should never do something like
new Service()
or
new Activity()
That's just bad and you're inviting a whole lot of trouble.
If you are going to call downloadFile() directly from your Activity, then why put it in a Service in the first place ? Isn't that redundant ? The reason for putting it in a Service is that the download operation is a non-UI task that requires no user interaction, which is what a Service is meant for. An Activity, on the other hand, is a UI-based component that is explicitly meant for user interaction. If the user dismisses your Activity while the download is in progress, then a NullPointerException gets thrown when the download completes and your code tries to post the data on the UI.
Why does the SyncService example provided by Google below use a Service instead of an IntentService? It is my understanding that IntentServices run in the background, while a regular Service will run in the main thread. For something with no UI that just updates data, why would you want it run in the main thread? Doesn't that risk frame-drops?
http://developer.android.com/training/sync-adapters/creating-sync-adapter.html#CreateSyncAdapterService
Is it possible to have a standalone IntentService? or does it need to be based off something running on the main thread? This is the only reason I can see why we would use a regular Service above.
It is my understanding that IntentServices run in the background, while a regular Service will run in the main thread.
Objects do not run on threads. Methods do.
IntentService inherits from Service. The main lifecycle methods on Service, notably onStartCommand() are called on the main application thread. IntentService happens to provide a background thread, which it uses to call your onHandleIntent() method, triggered by a call to onStartCommand().
For something with no UI that just updates data, why would you want it run in the main thread?
You don't.
Why does the SyncService example provided by Google below use a Service instead of an IntentService?
Because an IntentService is inappropriate here. Quoting the documentation that you linked to:
To do this, you need to create a bound Service that passes a special Android binder object from the sync adapter component to the framework. With this binder object, the framework can invoke the onPerformSync() method and pass data to it.
IntentService and the binding pattern do not work well together.
From a threading standpoint, onPerformSync() is called on a background thread, supplied by Android. Hence, even if IntentService were not ruled out based upon binding, you do not need another background thread, since onPerformSync() is already called on a background thread.
There are several ways to connect to Service to Activity. I am only interested in local service and my LocalService will stand there untill user stops it(which also means end of app). I might know things wrong, if so please correct me.
On the reference page, it is stated that in order to use methods of local service directly, we should use ServiceConnection. After binding, we can have a reference to LocalService class, and we can use methods of this LocalService directly. AFAIK the methods we call using this reference run on main thread with relevant Activity.
The thing that confuses me, what if I use skeleton structure and access LocalService's methods by directly its static reference (ie. by LocalService.getInstance()). Well, I have already used it and did not face any problem, but still I am not sure which one is better, and why.
Thanks in advance. I might add additional info if requested.
edit:
In my previously mentioned solution, no activity is keeping a reference to the LocalService.
It is used to
start some LongRunningAsyncTasks(which are all halted and reference-nullified before service stop),
update the app Notification,
get getFilesDir(),
to keep an enum value (whose reference is not kept elsewhere, it is just used for comparison) in order to access from everywhere(not worthy of using SharedPreferences).
show some toasts
aware of static references of activities and services because they can be a reason of memory leak. if you don't want your service run in main process, then extract it into another process and work with service connection.
If you don't need any feedback from service, then just don't use connection and simply use startService() with several commands which will be executed in onStartCommand() method of the service.
If you need feedback from service, but not frequently, then use startService() and feedback from service with sendBroadcast() or through Handler class.
If you need feedback frequently (for example update slider of media player), then it's better to use service connection.
Remember that your service can be killed anytime without executing method onDestroy() and without any notification, that's why keeping static reference is not good idea.
It appears from what you are saying that you probably don't need a Service at all. Looks like you are not doing any long-standing task in your LocalService. If that's the case, you can as well use AsyncTask or Handlers and be done. The motivation to use a Service (Local or otherwise) is to do some long standing task inside it and not stall the main UI thread. If your tasks are not gonna take up too much time, then you don't need a Service.
The Service does run on the main thread by default. Unless it's an IntentService where a worker thread is created for you automatically and all tasks are queued and handled one at a time in this worker thread. Otherwise, it's your responsibility to create a separate thread for your service tasks.
So, first analyze if you really need a Service. If your task can quickly get executed, then don't bother having a Service even.
Hope that helps.
We have a Service that takes care of several things in one of our activities. We are fairly new to Android and wondering what the perfect moment for binding to that service is. We only need the service for half of the interactions that are possible via the activity. So we have to settle for one of two possibilities:
bind to the Service when we really need it, which would add a fair amount of overhead implementation-wise
bind to the Service in the onCreate() method without the overhead of checking if the service is running, binding it on demand, maybe caching requests made etc.
What would be the "android way" here? Is a running service a lot of overhead or should it only be started when really needed? The service itself is really lightweight.
Personally I prefer to call bindService() in onCreate(), and after finish using it call unbindService() in onDestroy(). Reason for that is bindService() is actually an asynchronous call. which has not been well-documented in the API. When you call bindService(), the reference of binder object you get inside ServiceConnection.onServiceConnected() callback method is not get instantiated immediately, there is a lag in the meantime after calling bindService() and before binder object get instantiated and ready to use. so the most suitable place to call it is onCreate() as we usually do not preform much heavy operations and need use binder object immediately at this stage.