<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
從用途上來說Android的執行緒主要分為主執行緒和子執行緒兩類,主執行緒主要處理和介面相關的工作,子執行緒主要處理耗時操作。除Thread之外,Android中還有其他扮演執行緒的角色如AsyncTask、IntentService、HandleThread,其中AsyncTask的底層用到了執行緒池,IntentService和HandleThread的底層直接使用了執行緒。
AsyncTask內部封裝了執行緒池和Handler主要是為了方便開發者在線上程中更新UI;HandlerThread是一個具有訊息迴圈的執行緒,它的內部可以使用Handler;IntentService是一個服務,系統對其進行了封裝使其可以更方便的執行後臺任務,IntentService內部採用HandleThread來執行任務,當任務執行完畢後IntentService會自動退出。IntentService是一個服務但是它不容易被系統殺死因此它可以儘量的保證任務的執行。
主執行緒是指程序所擁有的的執行緒,在Java中預設情況下一個程序只能有一個執行緒,這個執行緒就是主執行緒。主執行緒主要處理介面互動的相關邏輯,因為介面隨時都有可能更新因此在主執行緒不能做耗時操作,否則介面就會出現卡頓的現象。主執行緒之外的執行緒都是子執行緒,也叫做工作執行緒。
Android沿用了Java的執行緒模型,也有主執行緒和子執行緒之分,主執行緒主要工作是執行四大元件及處理他們和使用者的互動,子執行緒的主要工作就是處理耗時任務,例如網路請求,I/O操作等。Android3.0開始系統要求網路存取必須在子執行緒中進行否則就會報錯,NetWorkOnMainThreadException
AsyncTask是一個輕量級的非同步任務類,它可以線上程池中執行非同步任務然後把執行進度和執行結果傳遞給主執行緒並在主執行緒更新UI。從實現上來說AsyncTask封裝了Thread和Handler,通過AsyncTask可以很方便的執行後臺任務以及主執行緒中存取UI,但是AsyncTask不適合處理耗時任務,耗時任務還是要交給執行緒池執行。
AsyncTask的四個核心類如下:
HandleThread繼承自Thread,它是一種可以使用Handler的Thread,它的實現在run方法中呼叫Looper.prepare()來建立訊息佇列然後通過Looper.loop()來開啟訊息迴圈,這樣在實際使用中就可以在HandleThread中建立Handler了。
@Override public void run() { mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); mTid = -1; }
HandleThread和Thread的區別是什麼?
IntentService繼承自Service並且是一個抽象的類因此使用它時就必須建立它的子類,IntentService可用於執行後臺耗時的任務,當任務執行完畢後就會自動停止。IntentService是一個服務因此它的優先順序要比執行緒高並且不容易被系統殺死,因此可以利用這個特點執行一些高優先順序的後臺任務,它的實現主要是HandlerThread和Handler,這點可以從onCreate方法中瞭解。
//IntentService#onCreate @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. super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); }
當IntentService第一次被啟動時回撥用onCreate方法,在onCreate方法中會建立HandlerThread,然後使用它的Looper建立一個Handler物件ServiceHandler,這樣通過mServiceHandler把訊息傳送到HandlerThread中執行。每次啟動IntentService都會呼叫onStartCommand,IntentService在onStartCommand中會處理每個後臺任務的Intent。
//IntentService#onStartCommand @Override public int onStartCommand(@Nullable Intent intent, int flags, int startId) { onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; } //IntentService#onStart @Override public void onStart(@Nullable Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); } 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); } }
onStartCommand是如何處理外界的Intent的?
在onStartCommand方法中進入了onStart方法,在這個方法中IntentService通過mserviceHandler傳送了一條訊息,然後這個訊息會在HandlerThread中被處理。mServiceHandler接收到訊息後會把intent傳遞給onHandlerIntent(),這個intent跟啟動IntentService時的startService中的intent是一樣的,因此可以通過這個intent解析出啟動IntentService傳遞的引數是什麼然後通過這些引數就可以區分具體的後臺任務,這樣onHandleIntent就可以對不同的後臺任務做處理了。當onHandleIntent方法執行結束後IntentService就會通過stopSelf(int startId)方法來嘗試停止服務,這裡不用stopSelf()的原因是因為這個方法被呼叫之後會立即停止服務但是這個時候可能還有其他訊息未處理完畢,而採用stopSelf(int startId)方法則會等待所有訊息都處理完畢後才會終止服務。呼叫stopSelf(int startId)終止服務時會根據startId判斷最近啟動的服務的startId是否相等,相等則立即終止服務否則不終止服務。
每執行一個後臺任務就會啟動一次intentService,而IntentService內部則通過訊息的方式向HandlerThread請求執行任務,Handler中的Looper是順序處理訊息的,這就意味著IntentService也是順序執行後臺任務的,當有多個後臺任務同時存在時這些後臺任務會按照外界發起的順序排隊執行。
執行緒池的優點:
Android的執行緒池的概念來自於Java中的Executor,Executor是一個介面,真正的執行緒的實現是ThreadPoolExecutor,它提供了一些列引數來設定執行緒池,通過不同的引數可以建立不同的執行緒池。
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }
ThreadPoolExecutor是執行緒池的真正實現,它的建構函式中提供了一系列引數,先看一下每個引數的含義:
ThreadPoolExecutor執行任務時大致遵循如下規則:
如果執行緒池中的執行緒數量沒有達到核心執行緒的數量那麼會直接啟動一個核心執行緒來執行任務;
如果執行緒池中執行緒數量已經達到或者超過核心執行緒的數量那麼會把後續的任務插入到佇列中等待執行;
如果任務佇列也無法插入那麼在基本可以確定是佇列已滿這時如果執行緒池中的執行緒數量沒有達到最大值就會立刻建立非核心執行緒來執行任務;
如果非核心執行緒的建立已經達到或者超過執行緒池的最大數量那麼就拒絕執行此任務,同時ThreadPoolExecutor會通過RejectedExecutionHandler丟擲異常rejectedExecution。
到此這篇關於Android中執行緒和執行緒池的文章就介紹到這了,更多相關Android執行緒和執行緒池內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45