当前位置:首页 » 安卓系统 » android异步线程

android异步线程

发布时间: 2022-09-19 18:41:34

‘壹’ Android多线程的四种方式:Handler、AsyncTask、ThreadPoolExector、IntentService

     异步通信机制,将工作线程中需更新UI的操作信息 传递到 UI主线程,从而实现 工作线程对UI的更新处理,最终实现异步消息的处理。Handler不仅仅能将子线程的数据传递给主线程,它能实现任意两个线程的数据传递。

(1)Message

    Message 可以在线程之间传递消息。可以在它的内部携带少量数据,用于在不同线程之间进行数据交换。除了 what 字段,还可以使用 arg1 和 arg2 来携带整型数据,使用 obj 来携带 Object 数据。

(2) Handler

    Handler 作为处理中心,用于发送(sendMessage 系列方法)与处理消息(handleMessage 方法)。

(3) MessageQueue

    MessageQueue 用于存放所有通过 Handler 发送的消息。这部分消息会一直存放在消息队列中,直到被处理。每个线程中只会有一个 MessageQueue 对象

(4) Looper

    Looper 用于管理 MessageQueue 队列,Looper对象通过loop()方法开启了一个死循环——for (;;){},不断地从looper内的MessageQueue中取出Message,并传递到 Handler 的 handleMessage() 方法中。每个线程中只会有一个 Looper 对象。

    AsyncTask 是一种轻量级的任务异步类,可以在后台子线程执行任务,且将执行进度及执行结果传递给 UI 线程。

(1)onPreExecute()

    在 UI 线程上工作,在任务执行 doInBackground() 之前调用。此步骤通常用于设置任务,例如在用户界面中显示进度条。

(2)doInBackground(Params... params)

    在子线程中工作,在 onPreExecute() 方法结束后执行,这一步被用于在后台执行长时间的任务,Params 参数通过 execute(Params) 方法被传递到此方法中。任务执行结束后,将结果传递给 onPostExecute(Result) 方法,同时我们可以通过 publishProgress(Progress) 方法,将执行进度发送给 onProgressUpdate(Progress) 方法。

(3)onProgressUpdate(Progress... values)

    在 UI 线程上工作,会在 doInBackground() 中调用 publishProgress(Progress) 方法后执行,此方法用于在后台计算仍在执行时(也就是 doInBackgound() 还在执行时)将计算执行进度通过 UI 显示出来。例如,可以通过动画进度条或显示文本字段中的日志,从而方便用户知道后台任务执行的进度。

(4)onPostExecute(Result result)

    在 UI 线程上工作,在任务执行完毕(即 doInBackground(Result) 执行完毕)并将执行结果传过来的时候工作。

使用规则:

(1)AsyncTask 是个抽象类,所以要创建它的子类实现抽象方法

(1)AsyncTask 类必须是在 UI 线程中被加载,但在Android 4.1(API 16)开始,就能被自动加载完成。

(2)AsyncTask 类的实例对象必须在 UI 线程中被创建。

(3)execute() 方法必须是在 UI 线程中被调用。

(4)不要手动调用方法 onPreExecute()、onPostExecute()、doInBackground()、onProgressUpdate()

(5)任务只能执行一次(如果尝试第二次执行,将抛出异常)。即一个AsyncTask对象只能调用一次execute()方法。

原理:

          其源码中原理还是 Thread 与 Handler 的实现,其包含 两个线程池,一个 Handler,如下所示:

名称类型作用

SERIAL_EXECUTOR线程池分发任务,串行分发,一次只分发一个任务

THREAD_POOL_EXECUTOR线程池执行任务,并行执行,执行的任务由 SERIAL_EXECUTOR 分发

InternalHandlerHandler负责子线程与主线程的沟通,通知主线程做 UI 工作

    一方面减少了每个并行任务独自建立线程的开销,另一方面可以管理多个并发线程的公共资源,从而提高了多线程的效率。所以ThreadPoolExecutor比较适合一组任务的执行。Executors利用工厂模式对ThreadPoolExecutor进行了封装。

Executors提供了四种创建ExecutorService的方法,他们的使用场景如下:

1. Executors.newFixedThreadPool()

    创建一个定长的线程池,每提交一个任务就创建一个线程,直到达到池的最大长度,这时线程池会保持长度不再变化。

当线程处于空闲状态时,它们并不会被回收,除非线程池被关闭。当所有的线程都处于活动状态时,新任务都会处于等待状态,直到有线程空闲出来。

只有核心线程并且不会被回收,能够更加快速的响应外界的请求。

2. Executors.newCachedThreadPool()

    创建一个可缓存的线程池,如果当前线程池的长度超过了处理的需要时,它可以灵活的回收空闲的线程,当需要增加时,它可以灵活的添加新的线程,而不会对池的长度作任何限制

    线程数量不定的线程池,只有非核心线程,最大线程数为 Integer.MAX_VALUE。当线程池中的线程都处于活动状态时,线程池会创建新的线程来处理新任务,否则利用空闲的线程来处理新任务。线程池中的空闲线程具有超时机制,为 60s。

    任务队列相当于一个空集合,导致任何任务都会立即被执行,适合执行大量耗时较少的任务。当整个线程池都处于限制状态时,线程池中的线程都会超时而被停止。

3. Executors.newScheledThreadPool()

    创建一个定长的线程池,而且支持定时的以及周期性的任务执行,类似于Timer。

    非核心线程数没有限制,并且非核心线程闲置的时候立即回收,主要用于执行定时任务和具有固定周期的重复任务。

4. Executors.newSingleThreadExecutor()

    创建一个单线程化的executor,它只创建唯一的worker线程来执行任务

    只有一个核心线程,保证所有的任务都在一个线程中顺序执行,意义在于不需要处理线程同步的问题。

    一般用于执行后台耗时任务,当任务执行完成会自动停止;同时由于它是一个服务,优先级要远远高于线程,更不容易被系统杀死,因此比较适合执行一些高优先级的后台任务。

使用步骤:创建IntentService的子类,重写onHandleIntent方法,在onHandleIntent中执行耗时任务

    原理:在源码实现上,IntentService封装了HandlerThread和Handler。onHandleIntent方法结束后会调用IntentService的stopSelf(int startId)方法尝试停止服务。

    IntentService的内部是通过消息的方式请求HandlerThread执行任务,HandlerThread内部又是一种使用Handler的Thread,这就意味着IntentService和Looper一样是顺序执行后台任务的

(HandlerThread:封装了Handler + ThreadHandlerThread适合在有需要一个工作线程(非UI线程)+任务的等待队列的形式,优点是不会有堵塞,减少了对性能的消耗,缺点是不能同时进行多个任务的处理,需要等待进行处理。处理效率低,可以当成一个轻量级的线程池来用)

‘贰’ Android 异步任务中允许有多个线程同时进行吗

允许的,异步多线程下载就是这样

‘叁’ android的动画是线程同步的还是异步的

ViewAnimation应该是同步的,view.startAnimation是在里面通过调用view.invalidate()来实现的;
PropertyAnimation应该是异步的吧,看代码里面用到了handler。

‘肆’ Android的handler机制的原理

Android的handler机制的原理分为异步通信准备,消息发送,消息循环,消息处理。

1、异步通信准备

在主线程中创建处理器对象(Looper)、消息队列对象(Message Queue)和Handler对象。

2、消息入队

工作线程通过Handler发送消息(Message) 到消息队列(Message Queue)中。

3、消息循环

消息出队: Looper循环取出消息队列(Message Queue) 中的的消息(Message)。

消息分发: Looper将取出的消息 (Message) 发送给创建该消息的处理者(Handler)。

4、消息处理

处理者(Handler) 接收处理器(Looper) 发送过来的消息(Message),根据消息(Message) 进行U操作。

handler的作用

handler是android线程之间的消息机制,主要的作用是将一个任务切换到指定的线程中去执行,(准确的说是切换到构成handler的looper所在的线程中去出处理)android系统中的一个例子就是主线程中的所有操作都是通过主线程中的handler去处理的。

Handler的运行需要底层的 messagequeue和 looper做支撑。



‘伍’ android 异步任务怎么给主线程传递数据

如果你Thread A获取数据是给另外一个Thread B使用的,那为什么不以Thread B为主,甚至直接让Thread B来请求数据数据呢。疑问:Thread A 请求数据,Thread B在那专门等待?为什么要这么设计?如果你非要这么干,那也是Thread A把数据处理好了,在启动Thread B,数据可以直接传递过去,thread没有process之间通信那么麻烦,直接共享

‘陆’ android 异步方法和子线程方法有什么区别

子线程没有控制并发数量,当并发过多的时候异步方法的作用就体现出来了。

异步是相对于同步而言的,顾名思义,同步就是各个通讯节点之间有统一的时钟,按照相同的时钟工作,异步相反,各节点之间没有统一的时钟,每个节点按照自己内部的时钟工作。
android在所有Thread当中,有一个Thread,我们称之为UI Thread。UI
Thread在Android程序运行的时候就被创建,是一个Process当中的主线程Main
Thread,主要是负责控制UI界面的显示、更新和控件交互。在Android程序创建之初,一个Process呈现的是单线程模型,所有的任务都在一个线程中运行。因此,我们认为,UI
Thread所执行的每一个函数,所花费的时间都应该是越短越好。而其他比较费时的工作(访问网络,下载数据,查询数据库等),都应该交由子线程去执行,以免阻塞主线程。

‘柒’ 关于Android获取线程执行完后的结果的问题!

其实谷歌早就意识到这个问题。Message里有一个send的方法。如下
Message msg = mhandler.obtainMessage(MSG_UPDATE, imgIndex, 0);
mhandler.sendMessage(msg);

然后重写handler的 handlerMessage方法,如下:
private Handler mhandler = new Handler(){
@Override
public void handleMessage(Message msg){
if(msg.what == MSG_UPDATE){
//你要的操作...

}
}
};

基本上就是这样啦!

‘捌’ Android 查询数据库采用ORM数据框架,是否还需要开启线程异步处理

直接引入的api就是异步的吧,不需要单独处理了。

‘玖’ android asynctask 多个实例是一个线程池吗

是的,android中的asynctask使用的是同一个线程池

可以查看asynctask的源码


我们可以看到一个THREAD_POOL_EXECUTOR静态变量,这个就是线程池

而且线程池的队列大小是128

热点内容
数据库数据的一致性 发布:2025-01-11 17:30:45 浏览:707
手机怎么设置手势安卓 发布:2025-01-11 17:15:54 浏览:964
威能壁挂炉解压阀 发布:2025-01-11 17:15:53 浏览:559
突破服务器ip限制 发布:2025-01-11 17:11:23 浏览:818
支付宝上传凭证 发布:2025-01-11 17:10:29 浏览:876
怎么打开行李箱的密码锁 发布:2025-01-11 17:09:51 浏览:593
苹果怎么删除id账号和密码 发布:2025-01-11 17:09:50 浏览:784
7z解压很慢 发布:2025-01-11 16:51:23 浏览:942
电脑改文档服务器 发布:2025-01-11 16:41:14 浏览:870
编译汇编语言实例 发布:2025-01-11 16:36:55 浏览:671