Thursday, March 21, 2013

Perform background processing with IntentService

android.app.IntentService is a subclass of android.app.Service that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.

IntentService


Create our custom IntentService, MyIntentService.java

You have to implement constructor of MyIntentService(). If you only override the default constructor of MyIntentService(String name) from IntentService, RuntimeException of java.lang.InstantiationException with Unable to instantiate service will be thrown.

package com.example.androidintentservice;

import android.app.IntentService;
import android.content.Intent;

public class MyIntentService extends IntentService {

public static final String ACTION_MyIntentService = "com.example.androidintentservice.RESPONSE";
public static final String EXTRA_KEY_IN = "EXTRA_IN";
public static final String EXTRA_KEY_OUT = "EXTRA_OUT";
String extraIn;
String extraOut;

public MyIntentService() {
super("com.example.androidintentservice.MyIntentService");
}

@Override
protected void onHandleIntent(Intent intent) {

//get input
extraIn = intent.getStringExtra(EXTRA_KEY_IN);
extraOut = "Result from MyIntentService: Hello " + extraIn;

//dummy delay for 5 sec
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //wait 3 sec

//return result
Intent intentResponse = new Intent();
intentResponse.setAction(ACTION_MyIntentService);
intentResponse.addCategory(Intent.CATEGORY_DEFAULT);
intentResponse.putExtra(EXTRA_KEY_OUT, extraOut);
sendBroadcast(intentResponse);
}

}


Modify layout to add a TextView to display result
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".MainActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<TextView
android:id="@+id/result"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</LinearLayout>


Main code in MainActivity.java. In order to receive result from IntentService, implement BroadcastReceiver, register in onCreate() and unregister in onDestroy(). To start MyIntentService, call startService() with coresponding intent.
package com.example.androidintentservice;

import android.os.Bundle;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.widget.TextView;

public class MainActivity extends Activity {

TextView textResult;

private MyBroadcastReceiver myBroadcastReceiver;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textResult = (TextView)findViewById(R.id.result);

//Start MyIntentService
Intent intentMyIntentService = new Intent(this, MyIntentService.class);
intentMyIntentService.putExtra(MyIntentService.EXTRA_KEY_IN, "Android-er");
startService(intentMyIntentService);

myBroadcastReceiver = new MyBroadcastReceiver();

//register BroadcastReceiver
IntentFilter intentFilter = new IntentFilter(MyIntentService.ACTION_MyIntentService);
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(myBroadcastReceiver, intentFilter);
}

@Override
protected void onDestroy() {
super.onDestroy();
//un-register BroadcastReceiver
unregisterReceiver(myBroadcastReceiver);
}

public class MyBroadcastReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
String result = intent.getStringExtra(MyIntentService.EXTRA_KEY_OUT);
textResult.setText(result);
}

}

}


Modify AndroidManifest.xml to add <service> of MyIntentService
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidintentservice"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.androidintentservice.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.example.androidintentservice.MyIntentService"></service>
</application>

</manifest>


download filesDownload the files.

Next:
- Share IntentService among Fragments
- Send data from IntentService to Activity, via additional Broadcast
- Generate Notification in IntentService


No comments:

Post a Comment