In this blog I will show you how to call REST API through a service. First question come to your mind that Why Service one use AsyncTask to call REST. Well, you can do that if you want to frustrate your user by calling same request again and again.
Basically the role of service is to continuously run in background without worrying about application process, or user interaction with application.
RESTService is made to implement as a subclass of services, while the services are meant to encapsulate longer running operations in an android app, they are not inherently threaded. This is something that often confuses new android developers. So we will create a new thread whenever new API request is fired. Here is the details of the code snippet
public class RestClient extends Service{ private static final String TAG = RestClient.class.getName(); private final ServiceBinder mBinder = new ServiceBinder(); private Looper mServiceLooper; private ServiceHandler mServiceHandler; @Override public void onCreate() { super.onCreate(); HandlerThread thread = new HandlerThread("RestClient[" + "SoPoint" + "]"); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); } @Override public int onStartCommand(Intent intent, int flags, int startId) { return START_STICKY; } @Override public IBinder onBind(Intent intent) { return mBinder; } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } @Override public void onDestroy() { mServiceLooper.quit(); } private void processRequest(Intent intent) { Message msg = mServiceHandler.obtainMessage(); msg.obj = intent; mServiceHandler.sendMessage(msg); } private void doWork(Intent intent){ Uri serviceURL = intent.getData(); Bundle extras = intent.getExtras(); int action = intent.getIntExtra(ServiceHelper.Constants.EXTRA_REQUEST, ServiceHelper.Constants.GET); Bundle params = extras.getParcelable(ServiceHelper.Constants.EXTRA_PARAMS); // Here we define our base request object which we will // send to our REST service via HttpClient. HttpRequestBase request = null; request = new HttpGet(); attachUriWithQuery(request, serviceURL, params); if (request != null) { HttpClient client = new DefaultHttpClient(); try{ // Finally, we send our request using HTTP. This is the synchronous // long operation that we need to run on this thread. ResponseHandler<String> res = new BasicResponseHandler(); String response = client.execute(request,res); Log.v(TAG,"Response---"+response); /*After getting response from server either we can pass the name of class used for parsing the response and instantiate using reflection or regiater a reciever in our activity*/ } catch (Exception e){ e.printStackTrace(); } } } class ServiceBinder extends Binder { public ServiceBinder(){ } public void processRequest(Intent intent) { RestClient.this.processRequest(intent); } } private class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { doWork((Intent)msg.obj); } }
In the code shown above we have created a handler thread and using that for creating new thread for every request.
Message msg = mServiceHandler.obtainMessage(); msg.obj = intent; mServiceHandler.sendMessage(msg);
And one more point to note how request is made using intent. We are passing Action Verb(GET,POST,PUT,DELETE) , and Service URL as URI. Once we get a response from server we could either deliver that response to Broadcast Receiver or we can directly pass the name of the class that is used for parsing that response in intent and get an object of that class using reflection.
If you find any bugs or have any questions, let me know in the comments, We will love to address them.
Happy coding…
Written By: Prateek Aggarwal, Android Mobile Developer, Mindfire Solutions
That’s a nice article .
Actually I have an issue regarding an android application
The application is about to transmit latitude and longitude at particular interval to a dedicated server . The application works fine for 10 to 20 min . but after that the app starts to transmit data at random interval . I am not able to get the exact cause .
Did you checked TimerTask. That may help in your case.
public static final int TIME_PERIOD=2000L; // Update period
// Initialize timer and schedule it tasks periodically
Timer mSensorTimer = new Timer(true);
mSensorTimer.schedule(new TimerTask() {
@Override
public void run() {
// Your code…..
}
}, TIME_PERIOD, TIME_PERIOD);