1

I'm building an Android library to collect data from the host app and send this data to an online server in the background. I realize that this would require some sort of multi-threading/use of a service/forking.

The application simply keeps adding data through library calls, and the library should handle the sending of this data in the background without disturbing the main UI.

How should I got about making this library? Should the entire library run on an Android Service? Should I just use another thread? This is my first foray into parallelism. I'm not sure what the best way to do this is.

A detailed response is appreciated.

ask
  • 2,160
  • 7
  • 31
  • 42
  • Using an AsyncTask is usually the best approach for one time threading if you are just doing a task and then the task ends. If you have long standing stuff running in the background the whole time, then services might be a better option. – Jay Snayder Jun 07 '13 at 20:06
  • This may help you: http://stackoverflow.com/questions/8267928/android-rest-client-sample – JustAnotherCoder Jun 07 '13 at 20:13

4 Answers4

1

Service would be a more reliable solution for situation You described.

I mean running background threads from service, not from Activity. Service itself does not provide separate thread by default, by the way.

The point is that Services have higher priority than acitivities so they will be destroyed with less probabilty, so your long-running task won't be interrupted.

Rodion Altshuler
  • 1,713
  • 1
  • 15
  • 31
1

Some of the answers aren't quite correct. Services (Android Service component) are NOT made to run in the background, they run in the default UI thread.

In all honesty, the question shouldn't be service or thread or anything. Your library does NOT need to kick start a service, it could simply be a class (singleton/static, whatever it is) that should extend AsyncTask (or anything else running in the background that I'll explain in a bit) and use the doInBackground method to send stuff to the server. Note AsyncTask is nothing but a Thread internally. So here's what I would do:

Let's call your library's main class that interfaces with your server ServerHelper. You can make this a singleton (or static but that's a separate discussion). Within this class create an innerclass say ServerHelperCommandTask and extend AsyncTask. You really should review AsyncTask in detail to understand how that works. Because you would be asked to override doInBackGround. Anything you put in this method will autmoatically get exectued in a separate thread off the UI. Then a callback is invoked called onPostExecute that you can override as you will get the result from doInBackground here. This OnPostExecute is called in the mainThread so you can check for say error results here, etc etc.

This would be the simplest method; however, there are many other methods and libraries that help you with networking and deal with all the background stuff internally. Google just release a library called Volley which you may be able to plugin and use as it would do all the parallel processing for you. But that may take a bit of learning curve. Hope you understand AsyncTasks as in your case if the data pushed isn't a lot, then AsyncTasks is the way to go. Also note that you can call multiple AsyncTasks but while that seems on the surface that it is kicking off multiple parallel threads, that isn't quite accurate since honeycomb as internally you can call 5 Asynctasks but all 5 of those tasks will be executed sequentially so you wouldn't have to worry much about serializing.

vkinra
  • 943
  • 1
  • 9
  • 16
  • So what the library does is this: The user keeps sending data to the library as long as the app is open. The library enqueues each bit of data. Whenever an internet connection is available, it dequeues it and sends a GET request to the server to send it the data. I'm not sure if ASync tasks should be sued for such a potentially long process. Any advice? – ask Jun 07 '13 at 21:25
  • I assume when you say 'each bit of data', you're not actually talking about 1 computer bit but as in a discreet data packet, correct? If so, and if the data packets aren't huge, then you can use AsyncTask even though these days AsyncTask for long network operations is not in vogue. When you make a GET call, I'm assuming you'll have a timeout say 5 seconds, so really as long as the data you send and the response is thin, you can use AsyncTasks, they are easy and pretty robust. You will keep popping data packet from queue and execure the ServerHelperCommdandTask. Take a look at Volley though! – vkinra Jun 07 '13 at 21:40
  • I'm not referring to the individual GET requests. For those, I'm using this: http://loopj.com/android-async-http/ (which seems similar to Volley). I would like to know how the queue and the class handling the asynchronous GET requests should be handled in parallel without slowing down the UI. The queue must obviously be synchronous and may bottle neck the whole process if it were run in the main thread. – ask Jun 07 '13 at 21:58
  • Ok, so basically your networking is ALREADY in an AsyncTask. So basically, sounds like you are concerned about deque'ing items from your que in the main thread. Don't be. I understand you can have a really really long queue. So here's what I would do-view (not remove) an item from the queue in your main thread->call asyncHttp on it (which will do the heavy networking in a sep thread) and provide callback on ui. If success, remove the item from the list in main thread. So until asyncHttp thread returns, you are not doing anything on ui thread. Viewing the first (or last) item list is inexpensiv – vkinra Jun 07 '13 at 22:10
  • What the Android documentation says about service: A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background – Bart Burg Aug 12 '15 at 11:59
0

You could do both but here's pros and cons for each solution :

Services are made to run in the background, even when your app is not in the foreground. sers usually don't like having services running for nothing. From your description it seems that you would only need to have this thread running when the app is in foreground right ? If so, a normal thread could do the job.

However, a service might be easier to implement.

Hope it helps

0

You should definitely use a Service in this situation. Async tasks and manually creating a thread is not really suitable for computations that need to run in the background for network communication. Use the Async task for long running local computations (e.g. for an algorithm doing sorting).

Note that if you use a service, it will by nature NOT run as a background thread! You need to handle threading manually. In order to save yourself from this hassle (especially if it is your first time with multi-threading) use an IntentService!

The IntentService may be invoked using the startService method as with any other service, but the IntentService class is able to handle multiple invocations as in a producer/consumer pattern. This means that you can queue commands automatically to the service just using the startService method. In the IntentService class that you make, you can then handle different types of commands by looking at the given action inside of the intent that is sent along as a parameter in the startService method.

Here is an example of how the implementation of an IntentService:

public class SimpleIntentService extends IntentService {

public SimpleIntentService() {
    super("SimpleIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
    String commnad = intent.getAction();

    //handle your command here and execute your desired code depending on this command
}

}

Rabie Jradi
  • 563
  • 4
  • 14
  • The application should be able to send data to the library at any time. Once the service starts, how do activities in the application send the service info. Also, the service's life time should not be governed by an individual activity's life span. – ask Jun 07 '13 at 21:27
  • With regards to the service lifetime I think you would benefit to look up the documentation written here https://developer.android.com/reference/android/app/Service.html#ProcessLifecycle From what I understand about your requirements, it doesn't seem like you need a separate process for your service. If this is the case though, I suggest to ask this as a separate question. Regarding how to send data to the service: There are several ways to do this: 1. Simply a static field or method 2. Using a singleton pattern 3. Using a SQLite database – Rabie Jradi Jun 08 '13 at 09:19