AsyncTask全解析
AsyncTask全解析1、AsyncTask介绍回顾上一节的问题:更新UI的方式有哪些?答案有:
Activity.runOnUiThread(Runnable)
View.post(Runnable),View.postDelay(Runnable, long)
Handler
AsyncTask
Rxjava
LiveData
本文的主角AsyncTask,本人现在用得比较少,更多用的是Rxjava。同时面试的时候知道AsyncTask是什么?怎么用?有什么不足之处或者需要注意什么?懂了这三个问题一般就可以了。至于看源码,可当作进阶,个人建议还是有必要学习一下的。那么AssyncTask究竟是什么呢?
AsyncTask是一个轻量级的异步任务类,可以在线程池里执行比较耗时的后台任务,然后把执行的进度和最后的结果传递给主进程,并在主进程中更新UI。使用容易,而且好理解。
1.1 AsyncTask的使用同样从使用入手,看看代码。以下代码以往文件里写数据为例:
private class FileTestTask extends AsyncTask<Void, Long, ...
Context
Context1、 什么是Context,能干什么?Context直译过来是“语境”,“上下文”,“环境”的意思。以前在学习嵌入式Linux的时候,也经常说到进程上下文,中断上下文。而在“安卓上下文”中,我们需要先明白安卓的应用模型是基于组件的应用设计模式,比如Activity和Service这些组件在运行的时候,都需要一个完整的Android工程环境。那么在代码里,这个“环境”由谁提供?那自然就是Context类。 作为Android代码里出镜率最高的Context,除了负责四大组件的交互场景外,还有很多的场景都需要用到Context,如:
获取系统属性,系统资源(color、string、drawable等)场景;
数据存储场景,如使用文件,SharedPreference,数据库的场景;
我们来看看源码里Context类系列:
Context如下代码,本身是一个纯abstract类,那么自然有对应的实现子类:ContextImpl和ContextWrapper,其中ContextImpl是Context真正的实现类,ContextWrapper类则和其名字一样,只是一个封 ...
Fragment全解析
Fragment全解析
1、什么是Fragment刚开始学习Activity的时候,一个界面就是一个Activity。那么,如果想在一个Activity界面上镶嵌另一个界面如何做呢?Fragment翻译为“片段,破片”,可以理解为“显示在Activity中的Activity”,为解决Android碎片化而生。Fragment可以作为一个Activity界面中独立的子界面,拥有自己的生命周期,也可以接受用户的触摸事件。我们可以在一个Activity界面上添加多个Fragment子界面,并且每个Fragment都可以动态的添加、删除、替换,从而使得安卓界面开发具有更强大的灵活性。
比如微信首页有“微信”、“通讯录”、“发现”、“我”,这4个子界面就是4个Fragment。我们在设计Fragment的时候,需要考虑模块化和可复用化。最后,总结一下使用Fragment的优势:
可以把一个Activity分为多个可复用的组件,使得UI开发更加有灵活性,之前一个Activity如果需要多个布局的话,就需要设置多个布局文件,又麻烦,性能也不高;
每个Fragment都是独立的个体,可以动态的添加 ...
HandlerThread
HandlerThread1、HandlerThread是什么?在安卓开发中,如果需要执行耗时操作,则可以开启子线程来完成,然而手动创建销毁线程又麻烦又消耗系统性能,因此可以使用线程池来完成。如果还需要在线程中使用Handler异步消息机制,或者需要实现子线程和子线程之间的通讯(Handler是主线程和子线程之间的通讯),那么就可以用HandlerThreaad。
HandlerThread是Google封装好的一个类,它的内部有自己的Looper对象,可以进行Loop轮询,用于执行多个耗时操作,而不需要多次开启线程,本质是使用Handler和Looper实现的。
2、HandlerThread怎么使用如果我们需要使用HandlerThread来读取一个大文件的内容,可以这么写:
public class Xuruictivity extends AppCompatActivity {
private static final int MSG_READ_INFO = 100;
Handler mMainHandler = new Handler();
...
Intent
Intent1、什么是IntentIntent,中文可翻译为“意图”,可用于Android同个应用程序中各个组件之间的交互,或者不同应用程序之间的交互。可以用来表明当前组件的思想和意图,比如想执行某个动作,想发送某些数据等等。每个组件都有不同的启动方法:
Activity:可以调用startActivity() 或 startActivityForResult() 传递 Intent来打开新的Activity;
Service:可以调用startService()传递 Intent 来启动服务,也可通过 bindService() 传递 Intent 来绑定到该服务;
Broadcast,可以调用sendBroadcast()、sendOrderedBroadcast() 或 sendStickyBroadcast() 等方法传递 Intent 来发起广播;
Intent分为显式Intent和隐式Intent,我们以打开新的Activity为例进行讲解。
1.1 显示Intent显式指定意图,系统就会根据我们指定的意图,打开我们想打开的Activity。Intent有如下构造函数: ...
IntentService
IntentService1、IntentService是什么?回顾Android实现线程异步的方法,有AsyncTask、HandlerThread、线程池、IntentService。其中IntentService其实是继承与Service的类,内部是由HandlerThread实现(HandlerThread本系列由专门的小节做介绍,不清楚的童鞋可以去看看)。常用于处理异步请求,处理完子线程的耗时操作后,会自动执行stopService()。
2、IntentService的使用我们用IntentService来实现在后台读取文件已经下载文件,直接上demo:
// XuruiIntentService.java
public class XuruiIntentService extends IntentService {
private static final String TAG = "XuruiIntentService";
public XuruiIntentService() {
//Inte ...
事件分发机制
事件分发机制
1、触摸事件分发流程在《Activity、Window、DecorView以及ViewRoot层级关系全解析》一节有下图:
我们知道View的结构是树形结构,View可以放在ViewGroup中,ViewGroup也可以放在另一个ViewGroup中,如此就形成了层层嵌套的关系。当我们触摸到屏幕后,就会生成一个Touch事件,常见的Touch事件有:
MotionEvent.ACTION_DOWN:按下
MotionEvent.ACTION_MOVE:滑动
MotionEvent.ACTION_CANCEL:非人为原因结束本次事件
MotionEvent.ACTION_UP:抬起 一般来说,一个事件会经过:按下 –》 滑动 –》抬起,这三个阶段,并在这个过程中会有非人为原因结束本次触摸流程。这些事件会在代码里会封装成一个MotionEvent。那么,当MotionEvent产生后,系统就会将其传递给View树,MotionEvent在View的层级传递,并最终得到处理的过程,就是触摸事件分发流程。一个流程的传递顺序是:
Activity/Window ...
Service
Service1、启动模式
1.1 StartService() 模式生命周期:onCreate()->onStartComment()->onDestroy()
生命周期见上图左时序图。当另一个组件可以通过调用 startService()方法来启动特定的服务,此时Service生命周期中的onStartCommand()方法被调用。当调用startService()方法时,其他组件需要在方法中传递一个intent参数,服务会在onStartCommand()中接收到intent并获取一些数据。比如ActivityA需要上报一些用户数据到服务器上面,就可以通过startService()来启动ServiceA,并将需要上报的数据传递给ServiceA,在ServiceA里面调用一些网络接口,把数据直接上报到服务器上面。
当一个服务以这种方式启动时,它的生命周期不再受启动它的组件的影响,它可以在后台无限期地运行,如上一段的例子里,就算ActvityA挂了,ServiceA仍在后台运行,直到ServiceA自己调用stopSelf()或者其他的组件手动调用stopServ ...
事件分发机制(下)
消息机制全解析(下)3、一问一答:常见问题汇总经过上面的学习,到了最激动人心的时刻了,揭秘下Handler常见的问题都如何回答。一开始觉得不知道如何回答的问题,你现在一定能轻松理解
3.1 Handler 引起的内存泄露原因以及最佳解决方案因为Handler一般是作为Activity的内部类,可以发送延迟执行的消息,如果在延迟阶段,我们把Activity关掉,此时因为该Activity还被Handler这个内部类所持有,导致Activity无法被回收,没有真正退出并释放相关资源,因此就造成内存泄漏。
工程上常用的方法是将 Handler 定义成静态的内部类,在内部持有 Activity 的弱引用,并在Acitivity的onDestroy()中调用handler.removeCallbacksAndMessages(null)及时移除所有消息。如果和面试官说了这两个方法,那你就100分过关了,但更进一步是建议将Handler抽离出来作为BaseHandler,然后每个Activity需要用到Handler的时候,就去继承BaseHandler。最佳解决方案具体代码:
// 这个是Bas ...
View
View绘制View有三个组件:
Measure:测量视图的高低
Layout:先通过measure测量出ViewGroup宽高,ViewGroup再通过layout方法根据自身宽高来确定自身位置
Draw:绘制视图
1、View绘制前的流程入门一段时间的同学都会知道,View绘制流程就是Measure() -> Laytou() -> Draw(),这三大方法。没错,不过在进行这三个方法之前,系统又做了什么准备工作呢?这就是本小节解决的问题。以下的图,是贯穿全文的总结图,放在文章开头,我们一步一步分析。
以下内容与本系列《Activity、Window、DecorView以及ViewRoot层级关系》(以下简称为《参考文档1》)一文内容重复较多,特别是源码分析,故具体源码请看参考文档1。从Activity创建到View的绘制,经过以下步骤:
Step1:初始化PhoneWindow和WindowManager
之前一节说过,Activity 是在 ActivityThread 的 performLaunchActivity 中进行创建的,并在attac ...