进程优先级
Foreground Process:前台进程,用户可见,被遮挡,虽然可见,但是不属于前台进程;
Background Process:后台进程,用户不可见,进程包含service,重要性高,也存在空进程,不做任何事情。
先立个大纲,明天写吧(2017年1月11日20:19:49)
线程调度
- 线程在程序中是独立的,并发的执行流,与进程相比,进程中的线程隔离程度小,共享内存,文件句柄,和进程应有的状态。
- 进程执行过程中拥有独立内存单元,多线程共享内存,提高程序运行效率。
- 线程共享进程代码段,进程共有数据,可很容易实现线程间相互通信。
- 进程间不能共享内存,线程共享相对容易的多。
- 创建线程实现多任务并发比多线程来说效率高。
thread runnable
创建线程和启动线程:
继承自Thread,重写run方法;
实现Runnable接口,并重写Runnable的run方法;
1 public class MyThread extends Thread { 2 3 @Override 4 public void run() { 5 super.run(); 6 Log.i("MyThreadName = ",this.getName()); 7 } 8 }
public class MyRunnable implements Runnable { @Override public void run() { Log.i("MyRunnable_ThreadName=",Thread.currentThread().getName()); } }
两种实现方式的区别:
采用Runnable实现,
- 线程类只是实现Runnable接口还可以继承自其他类;
- 可以实现共享同一target对象,使用相同线程处理同一资源的情况。
采用Thread实现:
不能继承其他父类;
无需使用Thread,currentThread()来获取当前线程,使用this就行。
线程生命周期:
new 新建状态,java虚拟机分配内存并初始化成员变量的值。
start 就绪状态,虚拟机创建栈和程序计数器,线程没有开始运行,只是可以运行。
运行状态:就绪状态线程获得CPU,执行run方法的线程执行体。
阻塞状态:
- 线程调用sleep方法主动放弃所占用的处理器资源;
- 线程调用阻塞IO方法,在该方法返回之前,线程阻塞;
- 线程获取同步监视器,同步监视器被其他线程持有;
- 线程等待通知(notify);
- 线程调用suspend将线程挂起,容易死锁,不建议使用。
重新进入就绪状态:
- 调用sleep的线程到了指定时间;
- 线程阻塞io已经返回;
- 线程成功获取同步监视器;
- 线程正在等待通知,其他线程发出通知;
- 处于关闭的线程调用resume恢复。
线程死亡:
- run方法执行完成,线程正常结束;
- 线程抛出Exception或者Error;
- 直接调用线程stop方法结束该线程(容易死锁,不建议使用)。
控制线程:
join()方法:调用线程阻塞,知道被join方法加入的join线程完成为止;
- join():等待被join线程执行完成;
- join(long millis):等待被join时间最长为millis毫秒,如果超出millis毫秒时间则不继续等待;
- join(long millis, int nanos):等待被join的线程时间为millis毫秒+nanos微秒;
AsyncTask
轻量级异步任务类,内部封装了Thread和Handler,但是不适合特别耗时的后台任务,特别耗时间的建议使用线程池。
三个泛型参数
1. Params
在执行AsyncTask时需要传入的参数,可用于在后台任务中使用。
2. Progress
后台任何执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为进度单位。
3. Result
当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值类型。
几个核心方法:
1. onPreExecute()(UI线程)
这个方法会在后台任务开始执行之间调用,用于进行一些界面上的初始化操作,比如显示一个进度条对话框。
2. doInBackground(Params...)(异步子线程)
这个方法中的所有代码都会在子线程中运行,我们应该在这里去处理所有的耗时任务。任务一旦完成就可以通过return语句来将任务的执行结果进行返回,如果AsyncTask的第三个泛型参数指定的是Void,就可以不返回任务执行结果。注意,在这个方法中是不可以进行UI操作的,如果需要更新UI元素,比如说反馈当前任务的执行进度,可以调用publishProgress(Progress...)方法来完成。
3. onProgressUpdate(Progress...)(UI线程)
当在后台任务中调用了publishProgress(Progress...)方法后,这个方法就很快会被调用,方法中携带的参数就是在后台任务中传递过来的。在这个方法中可以对UI进行操作,利用参数中的数值就可以对界面元素进行相应的更新。
4. onPostExecute(Result)(UI线程)
当后台任务执行完毕并通过return语句进行返回时,这个方法就很快会被调用。返回的数据会作为参数传递到此方法中,可以利用返回的数据来进行一些UI操作,比如关闭掉进度条对话框。
注意点:
- AsyncTask必须主线程调用;
- AsyncTask必须主线程创建对象;
- execute必须主线程调用;
- android 1.6之前 串行执行任务,1.6改成线程池并行执行,android3.0后采用一个线程串行执行,但是可以调用executeOnExcutor方法来并行执行任务。
AnsyTask源码分析:
首先ansyTask是一个抽象类,需要子类去实现:
1 public abstract class AsyncTask<Params, Progress, Result>{ 2 3 }
因为要调用AnsyTask需要初始化对象,所以我们先看下它的构造方法:
1 /** 2 * Creates a new asynchronous task. This constructor must be invoked on the UI thread. 3 */ 4 public AsyncTask() { 5 mWorker = new WorkerRunnable<Params, Result>() { 6 public Result call() throws Exception { 7 mTaskInvoked.set(true); 8 9 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 10 //noinspection unchecked 11 Result result = doInBackground(mParams); 12 Binder.flushPendingCommands(); 13 return postResult(result); 14 } 15 }; 16 17 mFuture = new FutureTask<Result>(mWorker) { 18 @Override 19 protected void done() { 20 try { 21 postResultIfNotInvoked(get()); 22 } catch (InterruptedException e) { 23 android.util.Log.w(LOG_TAG, e); 24 } catch (ExecutionException e) { 25 throw new RuntimeException("An error occurred while executing doInBackground()", 26 e.getCause()); 27 } catch (CancellationException e) { 28 postResultIfNotInvoked(null); 29 } 30 } 31 }; 32 }
必须在UI线程进行初始化操作,初始化mWorker,mFuture两个对象,初始化mWorker首先 mTaskInvoked.set(true);表示当前任务已经被调用过了,mWorker调用AsyncTask的doinBackground执行耗时操作,返回值传递给postResult方法。
看下postResult方法:
1 private Result postResult(Result result) { 2 @SuppressWarnings("unchecked") 3 Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, 4 new AsyncTaskResult<Result>(this, result)); 5 message.sendToTarget(); 6 return result; 7 }
看下hander:
1 private static Handler getHandler() { 2 synchronized (AsyncTask.class) { 3 if (sHandler == null) { 4 sHandler = new InternalHandler(); 5 } 6 return sHandler; 7 } 8 }
1 private static class InternalHandler extends Handler { 2 public InternalHandler() { 3 super(Looper.getMainLooper()); 4 } 5 6 @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"}) 7 @Override 8 public void handleMessage(Message msg) { 9 AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj; 10 switch (msg.what) { 11 case MESSAGE_POST_RESULT: 12 // There is only one result 13 result.mTask.finish(result.mData[0]); 14 break; 15 case MESSAGE_POST_PROGRESS: 16 result.mTask.onProgressUpdate(result.mData); 17 break; 18 } 19 } 20 }
很明显调用第13行进而调用:
1 private void finish(Result result) { 2 if (isCancelled()) { 3 onCancelled(result); 4 } else { 5 onPostExecute(result); 6 } 7 mStatus = Status.FINISHED; 8 }
如果取消调用onCancelled(result)否则调用onPostExcute(result)进行UI线程的操作。
然后我们代码中还会调用execute()方法:
1 @MainThread 2 public final AsyncTask<Params, Progress, Result> execute(Params... params) { 3 return executeOnExecutor(sDefaultExecutor, params); 4 }
1 @MainThread 2 public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, 3 Params... params) { 4 if (mStatus != Status.PENDING) { 5 switch (mStatus) { 6 case RUNNING: 7 throw new IllegalStateException("Cannot execute task:" 8 + " the task is already running."); 9 case FINISHED: 10 throw new IllegalStateException("Cannot execute task:" 11 + " the task has already been executed " 12 + "(a task can be executed only once)"); 13 } 14 } 15 16 mStatus = Status.RUNNING; 17 18 onPreExecute(); 19 20 mWorker.mParams = params; 21 exec.execute(mFuture); 22 23 return this; 24 }
sDefaultExecutor:
1 public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); 2 private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR; 3 private static class SerialExecutor implements Executor { 4 final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); 5 Runnable mActive; 6 7 public synchronized void execute(final Runnable r) { 8 mTasks.offer(new Runnable() { 9 public void run() { 10 try { 11 r.run(); 12 } finally { 13 scheduleNext(); 14 } 15 } 16 }); 17 if (mActive == null) { 18 scheduleNext(); 19 } 20 } 21 22 protected synchronized void scheduleNext() { 23 if ((mActive = mTasks.poll()) != null) { 24 THREAD_POOL_EXECUTOR.execute(mActive); 25 } 26 } 27 }
首先给ArrayDeque<Runnable>队列尾部插入runnable对象,run里面如果出现异常调用Executor的excute方法(THREAD_POOL_EXECUTOR.execute(mActive););
HandlerThread
如下面代码所示:HandlerThread是继承自Thread,并且可使用Handler的Thread,通过在线程里面实现Looper.prepare()和Looper.loop()实现创建队列,和轮训队列的操作。
HandlerThread源码:
1 /**
2 * Handy class for starting a new thread that has a looper. The looper can then be
3 * used to create handler classes. Note that start() must still be called.
4 *启动一个携带有looper的线程,用来创建handler类。启动这个线程通过start()来实现。
5 */
6 public class HandlerThread extends Thread {
7 //线程的优先级
8 int mPriority;
9 //当前线程id
10 int mTid = -1;
11 //当前线程持有的Looper对象
12 Looper mLooper;
13
14 //有参构造方法,优先级为默认优先级,
15 public HandlerThread(String name) {
16 super(name);
17 mPriority = Process.THREAD_PRIORITY_DEFAULT;
18 }
19
20 /**
21 * Constructs a HandlerThread.
22 *有参数构造方法,可以手动传递线程优先级。
23 * @param name
24 * @param priority The priority to run the thread at. The value supplied must be from
25 * {@link android.os.Process} and not from java.lang.Thread.
26 */
27 public HandlerThread(String name, int priority) {
28 super(name);
29 mPriority = priority;
30 }
31
32 /**
33 * Call back method that can be explicitly overridden if needed to execute some
34 * setup before Looper loops.
35 *回调方法可以实现在Looper.loop()之前的操作
36 */
37 protected void onLooperPrepared() {
38 }
39
40 /**
41 *关键部分
42 *
43 */
44
45 @Override
46 public void run() {
47 //获得当前线程的id
48 mTid = Process.myTid();
49 //准备循环条件
50 Looper.prepare();
51 synchronized (this) {
//获取到Looper对象
52 mLooper = Looper.myLooper();
//发出通知,当前线程已经创建mLooper对象成功,这里主要是通知getLooper方法中的wait
53 notifyAll();
54 }
//设置线程优先级
55 Process.setThreadPriority(mPriority);
//子类重写方法,进行循环操作之前的操作
56 onLooperPrepared();
//进行循环操作,不断的从MessageQueue中获取Message进行分发操作
57 Looper.loop();
58 mTid = -1;
59 }
60
61 /**
62 * This method returns the Looper associated with this thread. If this thread not been started
63 * or for any reason is isAlive() returns false, this method will return null. If this thread
64 * has been started, this method will block until the looper has been initialized.
65 * @return The looper.
*获取Looper对象,如果这个线程没start()或者其他原因,比如线程不存活isAlive为false的时候,这个方法返回null,如果线程启动了,这个放回会阻塞知道Looper初始化。
66 */
67 public Looper getLooper() {
68 if (!isAlive()) {
69 return null;
70 }
71
72 // If the thread has been started, wait until the looper has been created.
//如果线程已经启动,但是Looper还未创建的话,就等待,直到Looper创建成功
73 synchronized (this) {
74 while (isAlive() && mLooper == null) {
75 try {
76 wait();
77 } catch (InterruptedException e) {
78 }
79 }
80 }
81 return mLooper;
82 }
83
84 /**
85 * Quits the handler thread's looper.
86 * <p>
87 * Causes the handler thread's looper to terminate without processing any
88 * more messages in the message queue.
89 * </p><p>
90 * Any attempt to post messages to the queue after the looper is asked to quit will fail.
91 * For example, the {@link Handler#sendMessage(Message)} method will return false.
92 * </p><p class="note">
93 * Using this method may be unsafe because some messages may not be delivered
94 * before the looper terminates. Consider using {@link #quitSafely} instead to ensure
95 * that all pending work is completed in an orderly manner.
96 * </p>
97 *
98 * @return True if the looper looper has been asked to quit or false if the
99 * thread had not yet started running.
100 *
101 * @see #quitSafely
*结束线程循环,通过调用Looper的quit方法,其实最后调用是消息队列的quit方法。
102 */
103 public boolean quit() {
104 Looper looper = getLooper();
105 if (looper != null) {
106 looper.quit();
107 return true;
108 }
109 return false;
110 }
111
112 /**
113 * Quits the handler thread's looper safely.
114 * <p>
115 * Causes the handler thread's looper to terminate as soon as all remaining messages
116 * in the message queue that are already due to be delivered have been handled.
117 * Pending delayed messages with due times in the future will not be delivered.
118 * </p><p>
119 * Any attempt to post messages to the queue after the looper is asked to quit will fail.
120 * For example, the {@link Handler#sendMessage(Message)} method will return false.
121 * </p><p>
122 * If the thread has not been started or has finished (that is if
123 * {@link #getLooper} returns null), then false is returned.
124 * Otherwise the looper is asked to quit and true is returned.
125 * </p>
126 *
127 * @return True if the looper looper has been asked to quit or false if the
128 * thread had not yet started running.
*线程安全的退出线程的循环,其实最后也是调用的消息队列的quit方法
129 */
130 public boolean quitSafely() {
131 Looper looper = getLooper();
132 if (looper != null) {
133 looper.quitSafely();
134 return true;
135 }
136 return false;
137 }
138
139 /**
140 * Returns the identifier of this thread. See Process.myTid().
*获取线程id
141 */
142 public int getThreadId() {
143 return mTid;
144 }
145 }
第50行调用如下代码,进行Looper的初始化操作
1 /** Initialize the current thread as a looper. 2 * This gives you a chance to create handlers that then reference 3 * this looper, before actually starting the loop. Be sure to call 4 * {@link #loop()} after calling this method, and end it by calling 5 * {@link #quit()}.
*进行初始化操作,通过Looper.loop()进行循环处理,通过调用quit结束操作。 6 */ 7 public static void prepare() { 8 prepare(true); 9 } 10 11 private static void prepare(boolean quitAllowed) { 12 if (sThreadLocal.get() != null) { 13 throw new RuntimeException("Only one Looper may be created per thread"); 14 } 15 sThreadLocal.set(new Looper(quitAllowed)); 16 }
消息队列里面的quit方法:
1 void quit(boolean safe) {
2 if (!mQuitAllowed) {
3 throw new IllegalStateException("Main thread not allowed to quit.");
4 }
5
6 synchronized (this) {
7 if (mQuitting) {
8 return;
9 }
10 mQuitting = true;
11
12 if (safe) {
13 removeAllFutureMessagesLocked();
14 } else {
15 removeAllMessagesLocked();
16 }
17
18 // We can assume mPtr != 0 because mQuitting was previously false.
19 nativeWake(mPtr);
20 }
21 }
ThreadPoolExecutor
优点:
- 重用线程池中的线程,避免因为线程的原因和销毁所带来的性能消耗;
- 能有效控制线程池的并发数,避免资源抢占导致的阻塞现象。
看下ThreadPoolExecutor的构造方法:
1 public ThreadPoolExecutor(int corePoolSize, 2 int maximumPoolSize, 3 long keepAliveTime, 4 TimeUnit unit, 5 BlockingQueue<Runnable> workQueue, 6 ThreadFactory threadFactory, 7 RejectedExecutionHandler handler)
corePoolSize:核心线程池数,默认情况一直存活,即使是闲置状态。
maximumPoolSize:最大线程数,如果超出这个值,就会阻塞。
keepAliveTime:超时时长。超过非核心线程就会被回收。
unit:keepAliveTime的时间单位,(TimeUnit.SECOND,TimeUnit.MILLISECONDS,TimeUnit.MINUTES)。
workQueue:任务队列,execute方法提交的Runnable对象存在这个参数里面。
threadFactory:线程工程,为线程提供新线程的功能。
先贴个以前写线程池这块的工具类:
1 import java.util.concurrent.ExecutorService; 2 import java.util.concurrent.Executors; 3 import java.util.concurrent.Future; 4 import java.util.concurrent.ScheduledExecutorService; 5 import java.util.concurrent.TimeUnit; 6 7 /** 8 * @类名: ThreadUtils 9 * @描述: TODO(线程池工具类) 10 * @作者: soyoungboy 11 */ 12 public class ThreadUtils { 13 /** 14 * 单线程 15 */ 16 static ExecutorService singleThreadPool = Executors.newSingleThreadExecutor(); 17 private static volatile ThreadUtils instance = null; 18 /** 19 * 初始化的线程数,有待历史的验证,暂时弄4个 20 */ 21 public ExecutorService threadPool = Executors.newFixedThreadPool(4); 22 /** 23 * 执行延迟任务,类似Timer的效果 24 */ 25 public ScheduledExecutorService scheduleThreadPool = Executors.newScheduledThreadPool(2); 26 27 // private constructor suppresses 28 private ThreadUtils() { 29 30 } 31 32 public static ThreadUtils getInstance() { 33 // if already inited, no need to get lock everytime 34 if (instance == null) { 35 synchronized (ThreadUtils.class) { 36 if (instance == null) { 37 instance = new ThreadUtils(); 38 } 39 } 40 } 41 42 return instance; 43 } 44 45 /** 46 * 立即执行任务 47 * 48 * @param task ThreadUtils.getInstance().excute(run); 49 */ 50 public void excute(Runnable task) { 51 threadPool.execute(task); 52 } 53 54 /** 55 * 单线程持操作,主要用于数据库的读写异步操作 56 * 57 * @param task ThreadUtils.getInstance().excuteSingleThread(run); 58 * @return 59 */ 60 public Future excuteSingleThread(Runnable task) { 61 return singleThreadPool.submit(task); 62 } 63 64 ; 65 66 /** 67 * 延后执行任务 68 * 69 * @param task 70 * @param delay ThreadUtils.getInstance().schedule(run,1000); 71 */ 72 public void schedule(Runnable task, long delay) { 73 scheduleThreadPool.schedule(task, delay, TimeUnit.MILLISECONDS); 74 } 75 76 public Future execuse(final Task task) { 77 task.onstart(); 78 Future future = excuteSingleThread(new Runnable() { 79 @Override 80 public void run() { 81 try { 82 task.doInBackground(); 83 } catch (Exception e) { 84 task.transfer(null, Task.TRANSFER_DOERROR); 85 return; 86 } 87 task.transfer(null, Task.TRANSFER_DOUI); 88 } 89 }); 90 return future; 91 } 92 93 94 /** 95 * @param 设定文件 96 * @return void 返回类型 97 * @throws 在onDestory ()中执行[ThreadUtils.getInstance().shutdownThreadPool()] 98 * @Title: shutdownThreadPool 99 * @Description: TODO() 100 */ 101 public void shutdownThreadPool() { 102 threadPool.shutdownNow(); 103 } 104 105 /** 106 * @param 设定文件 107 * @return void 返回类型 108 * @throws 在onDestory ()中执行[ThreadUtils.getInstance().shutdownScheduleThreadPool()] 109 * @Title: shutdownThreadPool 110 * @Description: TODO() 111 */ 112 public void shutdownScheduleThreadPool() { 113 scheduleThreadPool.shutdownNow(); 114 115 } 116 117 /** 118 * @param 设定文件 119 * @return void 返回类型 120 * @throws 在onDestory ()中执行[ThreadUtils.getInstance().shutdownSingleThreadPool()] 121 * @Title: shutdownSingleThreadPool 122 * @Description: TODO(单线程池销毁操作) 123 */ 124 public void shutdownSingleThreadPool() { 125 singleThreadPool.shutdownNow(); 126 } 127 }
ThreadPoolExecutor是线程的真正实现;
线程池的分类:
1,FixedThreadPool
FixedThreadPool 线程数量固定的线程池,例如上面代码中如下字段:
1 public ExecutorService threadPool = Executors.newFixedThreadPool(4)
线程数量固定为4,线程空闲不回回收,除非线程关闭。
2,CacheThreadPool
线程数量不固定的线程池,最大线程数为Int最大值。
3,scheduledThreadPool
核心线程数固定,非核心线程不固定,闲置时非核心线程会立刻被回收,执行定时任务和具有固定周期的重复任务。
/** * 执行延迟任务,类似Timer的效果 */ public ScheduledExecutorService scheduleThreadPool = Executors.newScheduledThreadPool(2);
使用如下:
/** * 延后执行任务 * * @param task * @param delay ThreadUtils.getInstance().schedule(run,1000); */ public void schedule(Runnable task, long delay) { scheduleThreadPool.schedule(task, delay, TimeUnit.MILLISECONDS); }
4,SingleThreadExcutor
SingleThreadExcutor单线程池,只有一个核心线程,所有任务再同一线程中按序执行,不回存在线程同步问题。
声明:
/** * 单线程 */ static ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
使用:
/** * 单线程持操作,主要用于数据库的读写异步操作 * * @param task ThreadUtils.getInstance().excuteSingleThread(run); * @return */ public Future excuteSingleThread(Runnable task) { return singleThreadPool.submit(task); }
IntentService:
IntentService是继承自service并异步处理耗时操作,当任务执行完毕,自动停止。可以启动多次,耗时操作在IntentService的onHandIntent中进行,所有请求都在单一线程中,并且每次只执行一个异步任务。
IntentService的优点:
- 不用手动在service中创建线程;
- 操作完成后不用手动关闭service。
首先贴下IntentService的源码,很短:
/** * IntentService is a base class for {@link Service}s that handle asynchronous * requests (expressed as {@link Intent}s) on demand. Clients send requests * through {@link android.content.Context#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. * * <p>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 {@link #onHandleIntent(Intent)}. IntentService * will receive the Intents, launch a worker thread, and stop the service as * appropriate. * * <p>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. * * <div class="special reference"> * <h3>Developer Guides</h3> * <p>For a detailed discussion about how to create services, read the * <a href="{@docRoot}guide/topics/fundamentals/services.html">Services</a> developer guide.</p> * </div> * * @see android.os.AsyncTask */ public abstract class IntentService extends Service { private volatile Looper mServiceLooper; 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
//调用stopSelf自动关闭Service
onHandleIntent((Intent)msg.obj); stopSelf(msg.arg1); } } /** * Creates an IntentService. Invoked by your subclass's constructor. * * @param name Used to name the worker thread, important only for debugging. */ public IntentService(String name) { super(); mName = name; } /** * Sets intent redelivery preferences. Usually called from the constructor * with your preferred semantics. * * <p>If enabled is true, * {@link #onStartCommand(Intent, int, int)} will return * {@link Service#START_REDELIVER_INTENT}, so if this process dies before * {@link #onHandleIntent(Intent)} returns, the process will be restarted * and the intent redelivered. If multiple Intents have been sent, only * the most recent one is guaranteed to be redelivered. * * <p>If enabled is false (the default), * {@link #onStartCommand(Intent, int, int)} will return * {@link Service#START_NOT_STICKY}, and if the process dies, the Intent * dies along with it.
*设置当进程被重建时是否需要重新接受意图,true表示需要,并且当有多个意图时,只能保证最近的一个可以收到。 */ public void setIntentRedelivery(boolean enabled) { mRedelivery = enabled; } @Override public void onCreate() { // TODO: It would be nice to have an option to hold a partial wakelock // during processing, and to have a static startService(Context, Intent) // method that would launch the service & hand off a wakelock. //HandlerThread是集成自Thread的子类,与ServiceHandler进行关联 super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); } @Override public void onStart(@Nullable Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); } /** * You should not override this method for your IntentService. Instead, * override {@link #onHandleIntent}, which the system calls when the IntentService * receives a start request. * @see android.app.Service#onStartCommand
*这个不重写,主要重写onHandleIntent */ @Override public int onStartCommand(@Nullable Intent intent, int flags, int startId) { onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; } @Override public void onDestroy() { mServiceLooper.quit(); } /** * Unless you provide binding for your service, you don't need to implement this * method, because the default implementation returns null. * @see android.app.Service#onBind */ @Override @Nullable public IBinder onBind(Intent intent) { return null; } /** * 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 {@link #stopSelf}. * * @param intent The value passed to {@link * android.content.Context#startService(Intent)}. * This may be null if the service is being restarted after * its process has gone away; see * {@link android.app.Service#onStartCommand} * for details. */ @WorkerThread protected abstract void onHandleIntent(@Nullable Intent intent); }
继承自Service,在异步线程处理任务,通过startService启动,当任务完成会自动停止,不用手动处理,耗时任务会以队列形式在onHandleIntent中依次执行,然后结束。
oncreate()中创建并执行HandlerThread,也就是实现对MessageQqueue队列的循环遍历操作,将消息分发给Handler的handlerMessage方法 。
onStartCommand()调用onStart,发消息并由ServiceHandler的handleMessage来进行处理。
IntentService启动了线程里面带有Looper的线程,具有消息处理的能力,最后通过onHandleIntent()来处理,执行完后通过stopSelf()来停掉自己。
onHandleIntent抽象方法,需要子类实现。
1 onHandleIntent((Intent)msg.obj); 2 stopSelf(msg.arg1);