IntentService,是Service类的一个子类。同时,IntentService是一个抽象类,所以要想使用它必须要通过实现一个子类来使用它。
IntentService不同于普通Service的是: 1. 在IntentService中会默认创建一个子线程用于执行传递的Intent,这样在执行耗时操作时不需要手动去创建线程了 2. 在IntentService中创建工作队列,用于将 Intent 逐一传递给 onHandleIntent() 实现,这样就永远不必担心多线程问题。 3. 在处理完所有启动请求后停止服务,因此您永远不必调用 stopSelf()。
首先,创建一个类继承自IntentService
package com.zhangke.intentservicedemo;import android.app.IntentService;import android.content.Context;import android.content.Intent;import android.os.SystemClock;import android.util.Log;/** * */public class DownloadService extends IntentService { PRivate static final String TAG = "zhangke"; private static final String DOWN_URL = "down_url"; public DownloadService() { super("DownloadService"); } @Override protected void onHandleIntent(Intent intent) { if (intent == null) { return; } String url = intent.getStringExtra(DOWN_URL); downlaod(url); } /** * 模拟下载任务 * @param url */ private void downlaod(String url) { Log.e(TAG, "url = " + url +" 正在下载中..."); SystemClock.sleep(3000); } public static void startDownload(Context context, String url) { Intent intent = new Intent(context, DownloadService.class); intent.putExtra(DOWN_URL, url); context.startService(intent); }}在activity中使用DownloadService
package com.zhangke.intentservicedemo; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public int id = 0; public void startDownload(View view) { DownloadService.startDownload(this, "url" + id ++); }}布局文件:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.zhangke.intentservicedemo.MainActivity"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="startDownload" android:text="开始下载任务" /></LinearLayout>没当我们通过button点击一次,IntentServie就会被执行一次,如果一次性多点击几次,程序也次执行IntentService,并且多个任务是顺序执行的。
02-27 02:47:24.606 1883-1922/com.zhangke.intentservicedemo E/zhangke: url = url0 正在下载中...02-27 02:47:30.727 1883-1924/com.zhangke.intentservicedemo E/zhangke: url = url1 正在下载中...02-27 02:47:33.729 1883-1924/com.zhangke.intentservicedemo E/zhangke: url = url2 正在下载中...02-27 02:47:36.730 1883-1924/com.zhangke.intentservicedemo E/zhangke: url = url3 正在下载中...02-27 02:47:39.732 1883-1924/com.zhangke.intentservicedemo E/zhangke: url = url4 正在下载中...02-27 02:47:42.733 1883-1924/com.zhangke.intentservicedemo E/zhangke: url = url5 正在下载中...在IntentService中,主要使用到了HandlerThread。HandlerThread是Thread的一个子类,在该类中可以使用Handler。其实HandlerThread的实现原理非常简单,就是在run方法中通过Looper.prepare()来创建消息队列,然后通过Looper.loop()方法开启消息循环,整个实现流程如同ActivityThread.main()方法中MainLooper的初始化过程。
通过在Thread在初始化一个Looper,这样做的好处想必大家都清楚,那就是在Thread中可以使用Handler。
下面看看HandlerThread的run方法的具体实现:
@Overridepublic void run() { mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); mTid = -1;}新闻热点
疑难解答