2 Star 20 Fork 43

胡老皮 / 2023年Android面试题合集解析

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
Android异步任务和消息机制面试题.md 6.64 KB
一键复制 编辑 原始数据 按行查看 历史
胡老皮 提交于 2023-02-07 03:07 . Android异步任务和消息机制

这套Android面试题汇总大全,希望对大家有帮助哈~

全部答案,更新日期:2月6日,直接下载吧

全部答案,更新日期:2023年2月6日,直接下载吧!

下载链接:高清全答案解析,累计935页+大厂面试题 PDF

1、HandlerThread 的使用场景和用法?

HandlerThread 本质上是一个在子线程的handler(HandlerThread=Handler+Thread);

它的使用:

步骤1:创建HandlerThread实例对象 HandlerThread mHandlerThread = new HandlerThread("handlerThread");

步骤2:启动线程

mHandlerThread.start(); 步骤3:创建工作线程Handler&复写handleMessage () Handler workHandler = new Handler( handlerThread.getLooper() ) { @OverRide publicbooleanhandleMessage(Messagemsg){...//消息处理 return true; }

}); 步骤4:使用工作线程Handler向工作线程的消息队列发送 消 息 Message msg = Message.obtain(); msg.what = 2; //消息的标识 msg.obj = "B"; // 消息的存放 // b. 通过Handler发送消息到其绑定的消息队列 workHandler.sendMessage(msg); 步骤5:结束线程,即停止线程的消息循环 mHandlerThread.quit();

优势: 1.将loop运行在子线程中处理,减轻了主线程的压力,使主线程更流畅 2.串行执行,开启一个线程起到多个线程的作用 3.有自己的消息队列,不会干扰UI线程

劣势: 1.由于每一个任务队列逐步执行,一旦队列耗时过长,消息延时 2.对于IO等操作,线程等待,不能并发

2、IntentService 的应用场景和使用姿势?

IntentService 是 Service 的子类,默认为我们开启了一个工作线程,使用这个工作线程逐一处理所有启动请求,在任务执行完毕后会自动停止服务,使用简单,只要实现一个方法 onHandleIntent,该方法会接收每个启动请求的 Intent,能够执行后台工作和耗时操作。可以启动多次,而每一个耗时操作会以队列的方式在 IntentService的 回调方法中执行,并且,每一次只会执行一个工作线程,执行完第一个再执行第二个。并且等待所有消息都执行完后才终止服务。

IntentService适用于 APP 在不影响当前用户的操作的前提下,在后台默默的做一些操作。

IntentService源码:

1.通过HandlerThread单独开启一个名为IntentService的线程

2.创建一个名叫ServiceHandler的内部Handler

3.把内部Handler与HandlerThread所对应的子线程进行绑定

4.通过 onStartCommand()传递给服务 intent,依次插入到工作队列中,并逐个发送给onHandleIntent()

5.通过onHandleIntent()来依次处理所有Intent求对象所对应的任务

使用示例:

public class MyIntentService extends
IntentService {
public static final String TAG
="MyIntentService";
public MyIntentService()
{ super("MyIntentService"
);
}
@Override
protected void onHandleIntent(@Nullable Intent
intent) {
boolean isMainThread =
Thread.currentThread() ==
Looper.getMainLooper().getThread();
Log.i(TAG,"is main thread:"+isMainThread); //
这里会打印false,说明不是主线程
// 模拟耗时操作
download();
}
/**
* 模拟执行下载
*/
private void download(){ try {
Thread.sleep(5000);Log.i(TAG,"下载完成...");
}catch (Exception
e){ e.printStackTrace();
}
}
}

3、AsyncTask的优点和缺点?

AsyncTask 的 实 现 原 理 :

1.AsyncTask是一个抽象类,主要由Handler+2个线程池构 成,SERIAL_EXECUTOR是任务队列线程池,用于调度任务,按顺序排列执行,THREAD_POOL_EXECUTOR是执行 线程池,真正执行具体的线程任务。Handler用于工作线程 和主线程的异步通信。 2.AsyncTask<Params,Progress,Result>,其中Params是doInBackground()方法的参数类型,Result是doInBackground()方法的返回值类型,Progress是onProgressUpdate()方法的参数类型。 3.当执行execute()方法的时候,其实就是调用SERIAL_EXECUTOR的execute()方法,就是把任务添加到队列的尾部,然后从头开始取出队列中的任务,调用THREAD_POOL_EXECUTOR的execute()方法依次执行,当 队列中没有任务时就停止。 4.AsyncTask只能执行一次execute(params)方法,否则会报错。但是SERIAL_EXECUTOR和THREAD_POOL_EXECUTOR线程池都是静态的,所以可以形成队列。

4、AsyncTask只能执行一次execute()方法,那么为什么用线程池队列管理 ?

因为SERIAL_EXECUTOR和THREAD_POOL_EXECUTOR线程池都是静态的,所有的AsyncTask实例都共享这2个线程池, 因此形成了队列。

5、AsyncTask的onPreExecute()、doInBackground()、onPostExecute()方法的调用流程?

AsyncTask在创建对象的时候,会在构造函数中创建mWorker(workerRunnable)和mFuture(FutureTask)对象。mWorker实现了Callable接口的call()方法,在call()方法中,调用了doInBackground()方法,并在最后调用了postResult()方法,也就是通过Handler发送消息给主线程,在主线程中调用AsyncTask的finish()方法,决定是调 用onCancelled()还是onPostExecute(). mFuture实现了Runnable和Future接口,在创建对象时, 初始化成员变量mWorker,在run()方法中,调用 mWorker的call()方法。 当asyncTask执行execute()方法的时候,会先调用onPreExecute()方法,然后调用SERIAL_EXECUTOR的execute(mFuture),把任务加入到队列的尾部等待执行。执行的时候调用THREAD_POOL_EXECUTOR的execute(mFuture).

6、谈谈你对 Activity.runOnUiThread 的理解?

一般是用来将一个runnable绑定到主线程,在runOnUiThread源码里面会判断当前runnable是否是主线程,如果是直接run,如果不是,通过一个默认的空构造函数handler将runnable post 到looper里面,创建构造函数handler,会默认绑定一个主线程的looper对象

7、子线程能否更新UI?为什么?

8、谈谈 Handler 机制和原理?

9、为什么在子线程中创建Handler会抛异常?

10、试从源码角度分析Handler的post和sendMessage方法的区别和应用场景?

11、Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么?

由于篇幅原因,此处仅展示部分内容,查看更多Android面试题点击直接查看

全部答案,更新日期:2023年2月6日,直接下载吧!

下载链接:全部答案,整理好了

新增:高清全答案解析,累计935页+大厂面试题 PDF

1
https://gitee.com/hu-laopi/NewDevBooks.git
git@gitee.com:hu-laopi/NewDevBooks.git
hu-laopi
NewDevBooks
2023年Android面试题合集解析
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891