深入浅出理解IntentService

IntentService提供的功能也很类似AsyncTask,都是来处理异步工作的。

AsyncTask入门可参考,http://blog.csdn.net/lincyang/article/details/6617802
IntentService是继承自Service的,从源码上看,它是Service、HandlerThread和Handler的强强联合。源码也比AsyncTask简单,有兴趣的童鞋可以去看看。

工作流程也非常简单,客户端通过startService(Intent) 方法来调用,服务启动后,开启worker线程来顺序处理intent的任务。注意这里,一个intentService可以处理多个任务,只不过是一个接着一个的顺序来处理的;AsyncTask通常情况是每个任务启动一个新的asycnTask来工作,一个asyncTask只能使用一次,当你想再次使用的话,只好再new一个任务,否则要报异常的。从表象上看,这是两者的区别。当任务完成后,IntentService自动停止。


下面说说它的用法,和AsyncTask一样,使用IntentService必须要写一个类然后继承它。
因为IntentService本身是继承自Service,所以在使用的时候要先在AndroidManifest.xml中注册,否则报错:Unable to start service Intent not found
IntentService有7个方法,其中最重要的是onHandleIntent(),在这里调用worker线程来处理工作,每次只处理一个intent,像上面描述的,如果有多个,它会顺序处理,直到最后一个处理完毕,然后关闭自己。一点都不用我们操心,多好。
再介绍另一个很有意思的方法,setIntentRedelivery()。从字面理解是设置intent重投递。如果设置为true,onStartCommand(Intent, int, int)将会返回START_REDELIVER_INTENT,如果onHandleIntent(Intent)返回之前进程死掉了,那么进程将会重新启动,intent重新投递,如果有大量的intent投递了,那么只保证最近的intent会被重投递。这个机制也很好,大家可以尝试着用。
下面写个小例子,这个例子和之前asyncTask的一样,都是模拟处理耗时任务的。这里加上了广播机制来传递消息。
AndroidManifest.xml

[html]  view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:<a href="http://lib.csdn.net/base/15" class="replace_word" title="undefined" target="_blank" style="color:#df3434; font-weight:bold;">android</a>="http://schemas.android.com/apk/res/android"  
  3.       package="com.linc.TestIntentService"  
  4.       android:versionCode="1"  
  5.       android:versionName="1.0">  
  6.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
  7.         <activity android:name=".TestIntentService"  
  8.                   android:label="@string/app_name">  
  9.             <intent-filter>  
  10.                 <action android:name="android.intent.action.MAIN" />  
  11.                 <category android:name="android.intent.category.LAUNCHER" />  
  12.             </intent-filter>  
  13.         </activity>  
  14.         <service android:name=".LincIntentService"></service>  
  15.     </application>  
  16. </manifest>   

xml

[html]  view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >  
  7. <TextView    
  8.     android:id="@+id/text"  
  9.     android:layout_width="fill_parent"   
  10.     android:layout_height="wrap_content"   
  11.     android:textSize="30sp"  
  12.     android:textColor="#FF0000"  
  13.     android:text="@string/hello"  
  14.     />  
  15.       
  16.  <Button  
  17.     android:id="@+id/btnStart"  
  18.     android:layout_width="fill_parent"   
  19.     android:layout_height="wrap_content"   
  20.     android:text="Start"  
  21.  />  
  22.    
  23.   <Button  
  24.     android:id="@+id/btnSendOther"  
  25.     android:layout_width="fill_parent"   
  26.     android:layout_height="wrap_content"   
  27.     android:text="SendOtherBroadcast"  
  28.  />  
  29. </LinearLayout>  

Activity

[java]  view plain  copy
  1. package com.linc.TestIntentService;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.IntentService;  
  5. import android.content.BroadcastReceiver;  
  6. import android.content.Context;  
  7. import android.content.Intent;  
  8. import android.content.IntentFilter;  
  9. import android.os.Bundle;  
  10. import android.os.SystemClock;  
  11. import android.text.format.DateFormat;  
  12. import android.util.Log;  
  13. import android.view.View;  
  14. import android.widget.Button;  
  15. import android.widget.TextView;  
  16. import android.widget.Toast;  
  17.   
  18. public class TestIntentService extends Activity {  
  19.     private final static String Tag="TestIntentService";  
  20.     private TextView text;  
  21.     private Button btnStart;  
  22.     private Button btnSendOther;  
  23.     private MessageReceiver receiver ;  
  24.     /* 
  25.      * Action 
  26.      */  
  27.     private static final String ACTION_RECV_MSG = "com.linc.intent.action.RECEIVE_MESSAGE";  
  28.     private static final String ACTION_OTHER_MSG = "com.linc.intent.action.OTHER_MESSAGE";  
  29.       
  30.     /* 
  31.      * Message 
  32.      */  
  33.     private static final String MESSAGE_IN="message_input";  
  34.     private static final String MESSAGE_OUT="message_output";  
  35.       
  36.       
  37.     /** Called when the activity is first created. */  
  38.     @Override  
  39.     public void onCreate(Bundle savedInstanceState) {  
  40.         super.onCreate(savedInstanceState);  
  41.         setContentView(R.layout.main);  
  42.           
  43.         text=(TextView)findViewById(R.id.text);  
  44.         text.setText("准备");  
  45.         btnStart=(Button)findViewById(R.id.btnStart);  
  46.         btnStart.setOnClickListener(new View.OnClickListener() {  
  47.             @Override  
  48.             public void onClick(View v) {  
  49.                 // TODO Auto-generated method stub  
  50.                   
  51.               Intent msgIntent = new Intent(TestIntentService.this,   
  52.                       LincIntentService.class);  
  53.                 
  54.                msgIntent.putExtra(MESSAGE_IN, text.getText().toString());  
  55.                startService(msgIntent);  
  56.                   
  57.             }  
  58.         });  
  59.           
  60.         btnSendOther=(Button)findViewById(R.id.btnSendOther);  
  61.         btnSendOther.setOnClickListener(new View.OnClickListener() {  
  62.             @Override  
  63.             public void onClick(View v) {  
  64.                 // TODO Auto-generated method stub  
  65.             }  
  66.         });  
  67.           
  68.         //动态注册receiver  
  69.         IntentFilter filter = new IntentFilter(ACTION_RECV_MSG);  
  70.         filter.addCategory(Intent.CATEGORY_DEFAULT);  
  71.         receiver = new MessageReceiver();  
  72.         registerReceiver(receiver, filter);  
  73.         IntentFilter filter2 = new IntentFilter(ACTION_OTHER_MSG);  
  74.         filter2.addCategory(Intent.CATEGORY_DEFAULT);  
  75.         receiver = new MessageReceiver();  
  76.         registerReceiver(receiver, filter2);  
  77.     }  
  78.       
  79.     //广播来接收  
  80.     public class MessageReceiver extends BroadcastReceiver {  
  81.         @Override  
  82.         public void onReceive(Context context, Intent intent) {  
  83.               
  84.            String message = intent.getStringExtra(MESSAGE_OUT);  
  85.            text.setText(message);  
  86.              
  87.         Toast.makeText(context, "message",  
  88.              Toast.LENGTH_SHORT).show();  
  89.         }  
  90.     }  
  91.   
  92. }  

IntentService

[java]  view plain  copy
  1. package com.linc.TestIntentService;  
  2.   
  3. import android.app.IntentService;  
  4. import android.content.Intent;  
  5. import android.os.IBinder;  
  6. import android.os.SystemClock;  
  7. import android.text.format.DateFormat;  
  8. import android.util.Log;  
  9.   
  10. //IntentService  
  11. public class LincIntentService extends IntentService {  
  12.     /* 
  13.      * Action 
  14.      */  
  15.     private static final String ACTION_RECV_MSG = "com.linc.intent.action.RECEIVE_MESSAGE";  
  16.     private static final String ACTION_OTHER_MSG = "com.linc.intent.action.OTHER_MESSAGE";  
  17.       
  18.     /* 
  19.      * Message 
  20.      */  
  21.     private static final String MESSAGE_IN="message_input";  
  22.     private static final String MESSAGE_OUT="message_output";  
  23.       
  24.     private final static String Tag="---LincIntentService";  
  25.       
  26.     public LincIntentService() {  
  27.         super("LincIntentService");  
  28.         Log.d(Tag, "Constructor");   
  29.     }  
  30.   
  31.     @Override  
  32.     public IBinder onBind(Intent intent) {   
  33.         Log.d(Tag, "onBind()");   
  34.         return super.onBind(intent);   
  35.     }   
  36.     
  37.     @Override  
  38.     public void onCreate() {   
  39.         Log.d(Tag, "onCreate()");   
  40.         super.onCreate();   
  41.     }   
  42.     
  43.     @Override  
  44.     public void onDestroy() {   
  45.         Log.d(Tag, "onDestroy()");   
  46.         super.onDestroy();   
  47.     }   
  48.     
  49.     @Override  
  50.     public void onStart(Intent intent, int startId) {   
  51.         Log.d(Tag, "onStart()");   
  52.         super.onStart(intent, startId);   
  53.     }   
  54.     
  55.     @Override  
  56.     public int onStartCommand(Intent intent, int flags, int startId) {   
  57.         Log.d(Tag, "onStartCommand()");   
  58.         return super.onStartCommand(intent, flags, startId);   
  59.     }   
  60.     
  61.     @Override  
  62.     public void setIntentRedelivery(boolean enabled) {   
  63.         Log.d(Tag, "setIntentRedelivery()");   
  64.         super.setIntentRedelivery(enabled);   
  65.     }   
  66.   
  67.     @Override  
  68.     protected void onHandleIntent(Intent intent) {  
  69.         Log.d(Tag, "LincIntentService is onHandleIntent!");  
  70.         String msgRecv = intent.getStringExtra(MESSAGE_IN);  
  71.         for (int i = 0; i < 5; i++) {  
  72.             String resultTxt = msgRecv + " "  
  73.                 + DateFormat.format("MM/dd/yy hh:mm:ss", System.currentTimeMillis());  
  74.             Intent broadcastIntent = new Intent();  
  75.             broadcastIntent.setAction(ACTION_RECV_MSG);  
  76.             broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);  
  77.             broadcastIntent.putExtra(MESSAGE_OUT, resultTxt);  
  78.             sendBroadcast(broadcastIntent);  
  79.             SystemClock.sleep(1000);  
  80.         }  
  81.   
  82.     }  
  83. //    <service android:name=".LincIntentService"></service>  
  84. }  

从这两篇文章中可以看到,andorid提供这两个处理耗时任务的工具,为我们开发者带来了极大的便利。跟随源码,又可以让我们的水平上升一个档次。看来,android提供的文档和例子就是一个宝库,我们要好好的利用起来!
附上源码

[java]  view plain  copy
  1. /* 
  2.  * Copyright (C) 2008 The Android Open Source Project 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16.   
  17. package android.app;  
  18.   
  19. import android.content.Intent;  
  20. import android.os.Handler;  
  21. import android.os.HandlerThread;  
  22. import android.os.IBinder;  
  23. import android.os.Looper;  
  24. import android.os.Message;  
  25.   
  26. /** 
  27.  * IntentService is a base class for {@link Service}s that handle asynchronous 
  28.  * requests (expressed as {@link Intent}s) on demand.  Clients send requests 
  29.  * through {@link android.content.Context#startService(Intent)} calls; the 
  30.  * service is started as needed, handles each Intent in turn using a worker 
  31.  * thread, and stops itself when it runs out of work. 
  32.  * 
  33.  * <p>This "work queue processor" pattern is commonly used to offload tasks 
  34.  * from an application's main thread.  The IntentService class exists to 
  35.  * simplify this pattern and take care of the mechanics.  To use it, extend 
  36.  * IntentService and implement {@link #onHandleIntent(Intent)}.  IntentService 
  37.  * will receive the Intents, launch a worker thread, and stop the service as 
  38.  * appropriate. 
  39.  * 
  40.  * <p>All requests are handled on a single worker thread -- they may take as 
  41.  * long as necessary (and will not block the application's main loop), but 
  42.  * only one request will be processed at a time. 
  43.  * 
  44.  * @see android.os.AsyncTask 
  45.  */  
  46. public abstract class IntentService extends Service {  
  47.     private volatile Looper mServiceLooper;  
  48.     private volatile ServiceHandler mServiceHandler;  
  49.     private String mName;  
  50.     private boolean mRedelivery;  
  51.   
  52.     private final class ServiceHandler extends Handler {  
  53.         public ServiceHandler(Looper looper) {  
  54.             super(looper);  
  55.         }  
  56.   
  57.         @Override  
  58.         public void handleMessage(Message msg) {  
  59.             onHandleIntent((Intent)msg.obj);  
  60.             stopSelf(msg.arg1);  
  61.         }  
  62.     }  
  63.   
  64.     /** 
  65.      * Creates an IntentService.  Invoked by your subclass's constructor. 
  66.      * 
  67.      * @param name Used to name the worker thread, important only for debugging. 
  68.      */  
  69.     public IntentService(String name) {  
  70.         super();  
  71.         mName = name;  
  72.     }  
  73.   
  74.     /** 
  75.      * Sets intent redelivery preferences.  Usually called from the constructor 
  76.      * with your preferred semantics. 
  77.      * 
  78.      * <p>If enabled is true, 
  79.      * {@link #onStartCommand(Intent, int, int)} will return 
  80.      * {@link Service#START_REDELIVER_INTENT}, so if this process dies before 
  81.      * {@link #onHandleIntent(Intent)} returns, the process will be restarted 
  82.      * and the intent redelivered.  If multiple Intents have been sent, only 
  83.      * the most recent one is guaranteed to be redelivered. 
  84.      * 
  85.      * <p>If enabled is false (the default), 
  86.      * {@link #onStartCommand(Intent, int, int)} will return 
  87.      * {@link Service#START_NOT_STICKY}, and if the process dies, the Intent 
  88.      * dies along with it. 
  89.      */  
  90.     public void setIntentRedelivery(boolean enabled) {  
  91.         mRedelivery = enabled;  
  92.     }  
  93.   
  94.     @Override  
  95.     public void onCreate() {  
  96.         // TODO: It would be nice to have an option to hold a partial wakelock  
  97.         // during processing, and to have a static startService(Context, Intent)  
  98.         // method that would launch the service & hand off a wakelock.  
  99.   
  100.         super.onCreate();  
  101.         HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");  
  102.         thread.start();  
  103.   
  104.         mServiceLooper = thread.getLooper();  
  105.         mServiceHandler = new ServiceHandler(mServiceLooper);  
  106.     }  
  107.   
  108.     @Override  
  109.     public void onStart(Intent intent, int startId) {  
  110.         Message msg = mServiceHandler.obtainMessage();  
  111.         msg.arg1 = startId;  
  112.         msg.obj = intent;  
  113.         mServiceHandler.sendMessage(msg);  
  114.     }  
  115.   
  116.     @Override  
  117.     public int onStartCommand(Intent intent, int flags, int startId) {  
  118.         onStart(intent, startId);  
  119.         return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;  
  120.     }  
  121.   
  122.     @Override  
  123.     public void onDestroy() {  
  124.         mServiceLooper.quit();  
  125.     }  
  126.   
  127.     @Override  
  128.     public IBinder onBind(Intent intent) {  
  129.         return null;  
  130.     }  
  131.   
  132.     /** 
  133.      * This method is invoked on the worker thread with a request to process. 
  134.      * Only one Intent is processed at a time, but the processing happens on a 
  135.      * worker thread that runs independently from other application logic. 
  136.      * So, if this code takes a long time, it will hold up other requests to 
  137.      * the same IntentService, but it will not hold up anything else. 
  138.      * 
  139.      * @param intent The value passed to {@link 
  140.      *               android.content.Context#startService(Intent)}. 
  141.      */  
  142.     protected abstract void onHandleIntent(Intent intent);  
  143. }  

-------------------------------------------------------------------------------
个人总结与理解:
核心代码与思路:
1.点击启动IntentService(LincIntentService)
     Intent msgIntent = new Intent(TestIntentService.this,LincIntentService.class);
   msgIntent.putExtra(MESSAGE_IN, text.getText().toString());  //(一般封装了信息)
     startService(msgIntent);
2.IntentService被启动后,自动调用onHandleIntent方法处理传进来的intent(一般封装了信息)
   onHandleIntent(Intent intent) //此例子处理方法为:收到Intent后,把信息通过广播发出去
3.动态注册广播接收器,进行广播的接收.并重写onReceive方法进行广播处理。
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
http://blog.csdn.net/matrix_xu/article/details/7974393
个人总结与理解:
简而言之:
Service的出现为了解决Activity置于后台后容易被系统杀死
IntentService的出现是为了解决 Service要自己启动线程去处理耗时操作。
IntentService的原理就是自己启动一条线程然后利用Handler机制处理Intent,处理完成后,自己结束自己。
-------------------------------------------------------------------------------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值