Hello fellas, today I’d like to share with you the information on how to implement an Android Service that runs on background tasks. We use the startService method of Context for executing background tasks and Pending Intent as a callback method. Here is a code snippet from my Android Project.
ApiService.class
public static void RequestApi(WeakReference<Activity> contextRef, int request_type, HashMap<String,Object> extraInfos) {
Activity context = contextRef.get();
if(context == null) {
Log.wtf("API SERVICE", "Context is null");
}
Intent apiService = new Intent(context,ApiService.class);
PendingIntent pendingResult = ((Activity)context).createPendingResult(request_type,new Intent(),0);
apiService.putExtra(PENDING_RESULT_EXTRA,pendingResult);
apiService.putExtra(REQUEST_TYPE_EXTRA,request_type);
if (extraInfos != null) {
apiService.putExtra(STRING_EXTRA_INFO, extraInfos);
}
context.getApplicationContext().startService(apiService);
}
First we create an Intent to run on background. Then we create a PendingIntent instance with parameter of request_type which is a static constant variable in our ApiService class. Then we pass this pendingResult instance to our ApiService instance. Then we pass the request_type as a type and indicates the type of request. Finally we are ready to call startService for ApiService instance. Here are the constant variables of ApiService.class that are used in the code snippet above.
ApiService.class
public static final String PENDING_RESULT_EXTRA = "pending_result";
public static final String REQUEST_TYPE_EXTRA = "request";
public static final String STRING_EXTRA_INFO = "extra_info";
Now we need to implement pending Intent call back onHandleIntent.
Here we override callBack method of Service Intent. I’ll share full code for this method for people who are interested in my service calls.
ApiService.class
@Override
protected void onHandleIntent(@Nullable Intent intent) {
PendingIntent reply = intent.getParcelableExtra(PENDING_RESULT_EXTRA);
int request = intent.getIntExtra(REQUEST_TYPE_EXTRA,-1);
Intent result = new Intent();
try {
switch (request) {
case IS_SERVER_ALIVE_REQUEST:
boolean isServerAlive = this.isServerAlive();
result.putExtra(BOOLEAN_RESULT_EXTRA, isServerAlive);
break;
/* CODES ARE REMOVED FOR BACKEND SERVICE SECURITY*/
}
/*Send result to caller*/
try {
reply.send(this, SUCCESS_CODE, result);
} catch (Exception e) {
Log.e(TAG, e.toString());
}
} catch (Exception ex) {
result.putExtra(STRING_RESULT_EXTRA , ex.toString());
try {
reply.send(this, ERROR_CODE, result);
} catch (Exception e) {
result.putExtra(STRING_RESULT_EXTRA,e.toString());
Log.e(TAG, e.toString());
}
}
In the above code, you can see switch case usage for handling different kinds of service requests. We handle the returned information from Api Service Pending Intent instance here and then send this information with another pending intent instance with name reply which will be handled in caller instance.
ApiService.class
try { /* Sen*/
reply.send(this, ERROR_CODE, result);
} catch (Exception e) {
result.putExtra(STRING_RESULT_EXTRA,e.toString());
Log.e(TAG, e.toString());
}
Now let us have a look at the caller instance’s method of how we handle returned information from API service. First, we will show how we call the API service RequestApi method of ApiService class.
MainActivity.class
With below code we ,call RequestApi method from MainActivity instance.
ApiService.RequestApi(activityRef,ApiService.IS_SERVER_ALIVE_REQUEST,null);
Then we need to handle the returned information from ApiService’s insntace. it’s the same basic of how we handle PendingIntent callback.
In Main Activity we have overriden again ,
MainActivity.class
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult requestCode:" + requestCode + "resultCode:" + resultCode);
WeakReference<MainActivity> mainActivityRef = myContextPool.getMainActivityRef();
if (mainActivityRef == null || mainActivityRef.get() == null) {
Log.wtf(TAG,"Main activity is null");
}
MainActivity mainActivity = mainActivityRef.get();
/*Code will be continued*/
As you can see in above code snippet we override OnAcitivtyResult method.
Here we again will have same basic sets of rule. We have a switch case to determine which type of request is returned from ApiService Pending Intent instance.
MainActivity.class
switch (resultCode) {
case ApiService.SUCCESS_CODE:
switch (requestCode) {
case ApiService.GET_ALL_STATISTIC_REQUEST:
String statisticType;
****
If result Code is ApiService.SUCCESS_CODE, which means everything is all right. Then we can determine the type of ApiService Request.
MainActivity.class
*****
case ApiService.IS_SERVER_ALIVE_REQUEST:
String result = data.getStringExtra(ApiService.STRING_RESULT_EXTRA);
if (result.toLowerCase().contains("error") == false) {
MainActivity.API_IS_WORKING = true;
Toast.makeText(getApplicationContext(), result,Toast.LENGTH_SHORT).show();
} else {
String errMessage = result;
MainActivity.API_IS_WORKING = false;
closeApplicationDueToError(this,"Server is not responding Ret:" + errMessage);
}
break; /*case ApiService.IS_SERVE_ALIVE_REQUEST:*/
That’s it folks, In above code snippet we handle the ApiService.IS_SERVE_ALIVE_REQUEST and we do necessary jobs on mainActivity instance.