This "work queue processor" pattern is commonly used to offload tasks from an application's main thread. The IntentService class exists to simplify this pattern and take care of the mechanics. To use it, extend IntentService and implement onHandleIntent(Intent). IntentService will receive the Intents, launch a worker thread, and stop the service as appropriate.
All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application's main loop), but only one request will be processed at a time.
If you need parallel asynchronous processing then you need to look at the AsyncTask Tutorial. AsyncTask is limited to a single execution.
Steps involved in implementing an Android IntentService example using BroadcastReceiver
- Create a class file that extends the IntentService class and add stubs for the methods you need to implement. You should add a constructor with the name of your new service. You will need to implement just one other method called onHandleIntent().
- In your Activity start the Service with a call to startService() for an Intent instance. You can pass any data to the intent using the extras. The service takes over from here, catching each intent request, processing it, and shutting itself down when it’s all done. The main user interface remains responsive throughout the processing, allowing the user to continue to interact with the application.
- You need to send a broadcast from the onHandleIntent() method of the IntentService class after the processing is complete to let the BroadcastReceiver know results of the process.
- Define the BroadcastReceiver as subclass within the main activity and register the receiver.
In the example below, IntentService class has a delay of 10 seconds added to the processing which you must remove in you real application. This is there to simulate delay in processing heavy duty stuff that you may want to offload from the main activity and display the queue process as I fire three subsequent request. The program makes web requests and loads them in the main activity's WebView.
Source for AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.as400samplecode" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="13" /> <uses-permission android:name="android.permission.INTERNET" /> <application android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@android:style/Theme.Holo.Light"> <service android:name="MyWebRequestService"/> <activity android:name=".IntentServiceActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Source for main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingLeft="10dp"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="IntentService and BroadcastReceiver Example" android:textSize="25sp" android:paddingTop="20dp" /> <Button android:text="Send Request to The Service" android:id="@+id/sendRequest" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <LinearLayout android:layout_width="match_parent" android:id="@+id/linearLayout1" android:layout_height="wrap_content"> <TextView android:text="Watch for Response from IntentService" android:layout_height="wrap_content" android:id="@+id/textView1" android:textAppearance="?android:attr/textAppearanceLarge" android:layout_width="wrap_content" android:paddingTop="25dp" /> <TextView android:text="" android:layout_height="wrap_content" android:id="@+id/response" android:textAppearance="?android:attr/textAppearanceMedium" android:layout_width="wrap_content" android:layout_marginLeft="10dp" /> </LinearLayout> <WebView android:layout_width="match_parent" android:id="@+id/myWebView" android:layout_height="match_parent" /> </LinearLayout>
Source for MyWebRequestService.java
package com.as400samplecode; import java.io.ByteArrayOutputStream; import java.io.IOException; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.params.ConnManagerParams; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import com.as400samplecode.IntentServiceActivity.MyWebRequestReceiver; import android.app.IntentService; import android.content.Intent; import android.os.SystemClock; import android.text.format.DateFormat; import android.util.Log; public class MyWebRequestService extends IntentService{ public static final String REQUEST_STRING = "myRequest"; public static final String RESPONSE_STRING = "myResponse"; public static final String RESPONSE_MESSAGE = "myResponseMessage"; private String URL = null; private static final int REGISTRATION_TIMEOUT = 3 * 1000; private static final int WAIT_TIMEOUT = 30 * 1000; public MyWebRequestService() { super("MyWebRequestService"); } @Override protected void onHandleIntent(Intent intent) { String requestString = intent.getStringExtra(REQUEST_STRING); String responseString = requestString + " " + DateFormat.format("MM/dd/yy h:mmaa", System.currentTimeMillis()); String responseMessage = ""; SystemClock.sleep(10000); // Wait 10 seconds Log.v("MyWebRequestService:",responseString ); // Do some really cool here // I am making web request here as an example... try { URL = requestString; HttpClient httpclient = new DefaultHttpClient(); HttpParams params = httpclient.getParams(); HttpConnectionParams.setConnectionTimeout(params, REGISTRATION_TIMEOUT); HttpConnectionParams.setSoTimeout(params, WAIT_TIMEOUT); ConnManagerParams.setTimeout(params, WAIT_TIMEOUT); HttpGet httpGet = new HttpGet(URL); HttpResponse response = httpclient.execute(httpGet); StatusLine statusLine = response.getStatusLine(); if(statusLine.getStatusCode() == HttpStatus.SC_OK){ ByteArrayOutputStream out = new ByteArrayOutputStream(); response.getEntity().writeTo(out); out.close(); responseMessage = out.toString(); } else{ //Closes the connection. Log.w("HTTP1:",statusLine.getReasonPhrase()); response.getEntity().getContent().close(); throw new IOException(statusLine.getReasonPhrase()); } } catch (ClientProtocolException e) { Log.w("HTTP2:",e ); responseMessage = e.getMessage(); } catch (IOException e) { Log.w("HTTP3:",e ); responseMessage = e.getMessage(); }catch (Exception e) { Log.w("HTTP4:",e ); responseMessage = e.getMessage(); } Intent broadcastIntent = new Intent(); broadcastIntent.setAction(MyWebRequestReceiver.PROCESS_RESPONSE); broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); broadcastIntent.putExtra(RESPONSE_STRING, responseString); broadcastIntent.putExtra(RESPONSE_MESSAGE, responseMessage); sendBroadcast(broadcastIntent); } }
Source for IntentServiceActivity.java
package com.as400samplecode; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.view.View; import android.webkit.WebView; import android.widget.Button; import android.widget.TextView; public class IntentServiceActivity extends Activity { private MyWebRequestReceiver receiver; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); IntentFilter filter = new IntentFilter(MyWebRequestReceiver.PROCESS_RESPONSE); filter.addCategory(Intent.CATEGORY_DEFAULT); receiver = new MyWebRequestReceiver(); registerReceiver(receiver, filter); Button addButton = (Button) findViewById(R.id.sendRequest); addButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { Intent msgIntent = new Intent(IntentServiceActivity.this, MyWebRequestService.class); msgIntent.putExtra(MyWebRequestService.REQUEST_STRING, "http://www.amazon.com"); startService(msgIntent); msgIntent.putExtra(MyWebRequestService.REQUEST_STRING, "http://www.ebay.com"); startService(msgIntent); msgIntent.putExtra(MyWebRequestService.REQUEST_STRING, "http://www.yahoo.com"); startService(msgIntent); } }); } @Override public void onDestroy() { this.unregisterReceiver(receiver); super.onDestroy(); } public class MyWebRequestReceiver extends BroadcastReceiver{ public static final String PROCESS_RESPONSE = "com.as400samplecode.intent.action.PROCESS_RESPONSE"; @Override public void onReceive(Context context, Intent intent) { String responseString = intent.getStringExtra(MyWebRequestService.RESPONSE_STRING); String reponseMessage = intent.getStringExtra(MyWebRequestService.RESPONSE_MESSAGE); TextView myTextView = (TextView) findViewById(R.id.response); myTextView.setText(responseString); WebView myWebView = (WebView) findViewById(R.id.myWebView); myWebView.getSettings().setJavaScriptEnabled(true); try { myWebView.loadData(URLEncoder.encode(reponseMessage,"utf-8").replaceAll("\\+"," "), "text/html", "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } } }
No comments:
Post a Comment
NO JUNK, Please try to keep this clean and related to the topic at hand.
Comments are for users to ask questions, collaborate or improve on existing.