进程优先级
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
线程数量固定为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);