官方解释以下:java
//IntentService定义的三个基本点:是什么?怎么用?如何work?*/android
一、IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand.express
二、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.app
//解释了IntentService的好处,以及How to use IntentService*/dom
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.async
一、IntentService是Service类的子类,用来处理异步请求。ide
二、客户端能够经过startService(Intent)方法传递请求给IntentService函数
三、IntentService在onCreate()函数中经过HandlerThread单独开启一个线程来处理全部Intent请求对象(经过startService的方式发送过来的)所对应的任务,这样以避免事务处理阻塞主线程。
四、执行完所一个Intent请求对象所对应的工做以后,若是没有新的Intent请求达到,则自动中止Service;不然执行下一个Intent请求所对应的任务。
五、IntentService在处理事务时,仍是采用的Handler方式,建立一个名叫ServiceHandler的内部Handler,并把它直接绑定到HandlerThread所对应的子线程。 ServiceHandler把处理一个intent所对应的事务都封装到叫作onHandleIntent的虚函数;所以咱们直接实现虚函数onHandleIntent,再在里面根据Intent的不一样进行不一样的事务处理就能够了。
This method is invoked on the worker thread with a request to process. Only one Intent is processed at a time, but the processing happens on a worker thread that runs independently from other application logic. So, if this code takes a long time, it will hold up other requests to the same IntentService, but it will not hold up anything else. When all requests have been handled, the IntentService stops itself, so you should not call stopSelf().
一、该函数用于针对Intent的不一样进行不一样的事务处理.执行完所一个Intent请求对象所对应的工做以后,若是没有新的Intent请求达到,
则自动中止Service;不然ServiceHandler会取得下一个Intent请求传人该函数来处理其所对应的任务。
二、全部请求都在一个单线程中,不会阻塞应用程序的主线程(UI Thread),可是同一时间只处理一个请求。
IntentService的特色:
基于以上,IntentService与Service比较的好处有:
固然,IntentService的缺点也是显而易见:
因为是单个的worker thread,因此任务须要排队,不适合大多数的多任务状况;
主要由MainActivity和MyIntentService构成,在MainActivity中启动服务,并传递两个参数a和b,在MyIntentService中获取参数,求和,并经过发送广播的形式向UI返回结果,而后MainActivity在接收到广播以后更新UI。
代码以下:
public class MainActivity extends AppCompatActivity { private LinearLayout ll_container; private BroadcastReceiver forSumReceiver=new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.i("TAG","onReceive ()"); if(intent.getAction()==Constans.ACTION_RESULT){ int a=intent.getIntExtra(Constans.A,0); int result=intent.getIntExtra(Constans.RESULT,0); Log.i("TAG","onReceive --result:"+result); handleResult(a,result); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ll_container= (LinearLayout)findViewById(R.id.ll_container); Log.i("TEST","MainActivity:"+android.os.Process.myTid()); registerBroadcast(); } private void handleResult(int a,int result){ TextView textView=(TextView)ll_container.findViewWithTag(a); String old=textView.getText().toString(); String newText=old.replaceAll(" 正在计算中...",String.valueOf(result)+" 计算Success"); textView.setText(newText); } private void registerBroadcast(){ IntentFilter intentFilter=new IntentFilter(); intentFilter.addAction(Constans.ACTION_RESULT); registerReceiver(forSumReceiver,intentFilter); } private int a=1; public void addTask(View view){ int b=new Random().nextInt(101)+1; MyIntentService.startMyIntentService(this,a,b); TextView textView=new TextView(this); textView.setText(a+"+"+b+"= "+ " 正在计算中..."); textView.setTag(a); ll_container.addView(textView); a++; } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(forSumReceiver); } }
public class MyIntentService extends IntentService { public MyIntentService() { //必须实现父类的构造方法 super("MyIntentService"); } @Override public void onCreate() { Log.i("TEST","onCreate()"); super.onCreate(); } @Override public void onStart(Intent intent, int startId) { Log.i("TEST","onStart()"); super.onStart(intent, startId); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i("TEST","onStartCommand()"); return super.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { Log.i("TEST", "onBind()"); return super.onBind(intent); } @Override public void onDestroy() { Log.i("TEST","onDestroy()"); super.onDestroy(); } @Override protected void onHandleIntent(Intent intent) { Log.i("TEST","onHandleIntent():"+android.os.Process.myTid()); if (intent!=null){ String action=intent.getAction(); if(Constans.ACTION_FOR_SUM.equals(action)){ int a=intent.getIntExtra(Constans.A,0); int b=intent.getIntExtra(Constans.B,0); int result=a+b; Log.i("TEST","result: "+result); handleResult(a,result); } } } private void handleResult(int a,int result){ try{ //模拟计算耗时 Thread.sleep(3000); Intent intent=new Intent(Constans.ACTION_RESULT); intent.putExtra(Constans.RESULT,result); intent.putExtra(Constans.A,a); sendBroadcast(intent); }catch (InterruptedException e){ e.printStackTrace();; } } public static void startMyIntentService(Context context,int a,int b){ Intent intent=new Intent(context,MyIntentService.class); intent.setAction(Constans.ACTION_FOR_SUM); intent.putExtra(Constans.A,a); intent.putExtra(Constans.B,b); context.startService(intent); } }
07-08 10:18:51.579 com.troy.intentservicedemo I/TEST: MainActivity:30060 07-08 10:19:26.009 com.troy.intentservicedemo I/TEST: onCreate() 07-08 10:19:26.009 com.troy.intentservicedemo I/TEST: onStartCommand() 07-08 10:19:26.009 com.troy.intentservicedemo I/TEST: onStart() 07-08 10:19:26.039 com.troy.intentservicedemo I/TEST: onHandleIntent():30223 07-08 10:19:26.039 com.troy.intentservicedemo I/TEST: result: 23 07-08 10:19:29.100 com.troy.intentservicedemo I/TEST: onDestroy() 07-08 10:19:31.839 com.troy.intentservicedemo I/TEST: onCreate() 07-08 10:19:31.849 com.troy.intentservicedemo I/TEST: onStartCommand() 07-08 10:19:31.849 com.troy.intentservicedemo I/TEST: onStart() 07-08 10:19:31.869 com.troy.intentservicedemo I/TEST: onHandleIntent():30305 07-08 10:19:31.869 com.troy.intentservicedemo I/TEST: result: 52 07-08 10:19:34.899 com.troy.intentservicedemo I/TEST: onDestroy()
IntentService是Service的子类,拥有Service的全部生命周期方法;同时还有本身的ServiceHandler;
public abstract class IntentService extends Service { private volatile Looper mServiceLooper;//volatile关键字保证同步,保证可见性 private volatile ServiceHandler mServiceHandler; private String mName; private boolean mRedelivery; private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { onHandleIntent((Intent)msg.obj); stopSelf(msg.arg1); } } public IntentService(String name) {//构造方法 super(); mName = name; }
IntentService 其实是Looper,Handler,Service 的集合体,他不只有服务的功能,还有处理和循环消息的功能。
@Override
public void onCreate() { super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); }
IntentService建立时就会建立Handler线程(HandlerThread)而且启动,而后再获得当前线程的Looper对象来初始化IntentService的mServiceLooper,接着建立mServicehandler对象。
@Override
public void onStart(Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); }
当你启动IntentService的时候,就会产生一条附带startId和Intent的 Message并发送到MessageQueue中,接下来Looper发现MessageQueue中有Message的时候,就会中止Handler 处理消息。
@Override
public void handleMessage(Message msg) { onHandleIntent((Intent)msg.obj); stopSelf(msg.arg1); }
接着调用 onHandleIntent((Intent)msg.obj),这是一个抽象的方法,其实就是咱们要重写实现的方法,咱们能够在这个方法里面处理咱们的工做.当任务完成时就会调用stopSelf(msg.arg1)这个方法来结束指定的工做。
注意下:回调完成后回调用 stopSelf(msg.arg1),注意这个msg.arg1是个int值,至关于一个请求的惟一标识。每发送一个请求,会生成一个惟一的标识,而后将请求放入队列,当所有执行完成(最后一个请求也就至关于getLastStartId == startId),或者当前发送的标识是最近发出的那一个(getLastStartId == startId),则会销毁咱们的Service.若是传入的是-1则直接销毁。
当全部的工做执行完后:就会执行onDestroy方法。
@Override
public void onDestroy() { mServiceLooper.quit(); }
服务结束后调用这个方法 mServiceLooper.quit()使looper停下来。
一、 IntentService是一个基于消息的服务,每次启动该服务并非立刻处理你的工做,而是首先会建立对应的Looper,Handler而且在MessageQueue中添 加的附带客户Intent的Message对象, 当Looper发现有Message的时候接着获得Intent对象经过在 onHandleIntent((Intent)msg.obj)中调用你的处理程序. 处理完后即会中止本身的服务. 意思是Intent的生命周期跟你的 处理的任务是一致的. 因此这个类用下载任务中很是好,下载任务结束后服务自身就会结束退出。
二、IntentService是不适合用于bindService()这样的启动方式的。其次咱们经过startService屡次启动Service时,至关于在MessageQueue中添加了多个任务,就能够实现多任务按照顺序执行。
三、只有在onHandleIntent()方法中执行的代码才是在工做线程中运行的。IntentService的中止不是由于在handleMessage() 中执行了stopSelf(msg.arg1);而是系统本身中止的。