Activity生命周期(7个方法)
Fragment (生命周期11个方法)
Fragment 执行hide、show生命周期执行:
当使用hide、show方法来控制Fragment使用时,Fragment生命周期将不执行,在onResume以及onPause方法处理的事情将由onHiddenChange进行管理,当Fragment调用hide隐藏时,
该方法会被调用,传入参数为true,表示该Fragment被隐藏了,当Fragment调用了show方法后,该方法传入的参数为false,表示该Fragment正在显示。
onHiddenChange 回调时机:
当使用add()+show()、hide()跳转到新的Fragment时,旧的Fragment回调 onHiddenChanged(),不会回调onStop()等生命周期方法,而新的Fragment在创建时是不会回调onHiddenChanged()。
https://www.cnblogs.com/zty-Love/p/8656151.html
Activity启动模式(4种)
Service (2)和BroadCast
Service 两种启动模式
Android APP 启动流程
Activity启动流程
Q:Activity的启动过程?
技术点:Activity启动、ActivityManagerServie、ApplicationThread
思路:可大致介绍Activity启动过程涉及到的类,尤其是ActivityManagerServie、ApplicationThread从中发挥的作用。
调用startActivity()后经过重重方法会转移到ActivityManagerService的startActivity(),并通过一个IPC回到ActivityThread的内部类ApplicationThread中,并调用其scheduleLaunchActivity()将启动Activity的消息发送并交由Handler H处理。Handler H对消息的处理会调用handleLaunchActivity()->performLaunchActivity()得以完成Activity对象的创建和启动。
Android事件分发机制 详解攻略,您值得拥有
首先你需要知道一点,只要你触摸到了任何一个控件,就一定会调用该控件的dispatchTouchEvent方法。那当我们去点击按钮的时候,就会去调用Button类里的dispatchTouchEvent方法,可是你会发现Button类里并没有这个方法,那么就到它的父类TextView里去找一找,你会发现TextView里也没有这个方法,那没办法了,只好继续在TextView的父类View里找一找,这个时候你终于在View里找到了这个方法。
[https://blog.csdn.net/carson_ho/article/details/54136311](https://blog.csdn.net/carson_ho/article/details/54136311)
事件传递机制 (同时执行几个方法 on touch
on touch event
up (on click )
on long click
ACTION_DOWN:主要包括了setPressed和checkForLongClick两个操作:
setPressed用于设置按下状态,此时PFLAG_PRESSED标志位被设置。
checkForLongClick用于检查LongClick是否可以触发,以及发送延迟消息来响应长按事件。
)
view绘制流程
Handler Loop 机制
IPC
Bindle 机制
多线程
jvm
jmm
okhttp
retrofit
glide
rxjava
volley 请问volley为什么不适合传输大数据
volley中为了提高请求处理的速度,采用了ByteArrayPool进行内存中的数据存储的,如果下载大量的数据,这个存储空间就会溢出,所以不适合大量的数据,但是由于他的这个存储空间是内存中分配的,当存储的时候优是从ByteArrayPool中取出一块已经分配的内存区域, 不必每次存数据都要进行内存分配,而是先查找缓冲池中有无适合的内存区域,如果有,直接拿来用,从而减少内存分配的次数 ,所以他比较适合大量的数据量少的网络数据交互情况。
HttpClient和HttpURLConnection区别
1、HttpURLConnection是java的标准类,没有做封装,用起来比较原始
2、HttpClient是开源框架,封装了访问HTTP的请求头、参数、内容体、响应等;HttpURLConnection中的输入输出流操作,在这个接口中被统一封装成了HttpPost(HttpGet)和HttpResponse。这样,减少了操作的繁琐性。
性能方面:
HttpURLConnection的访问速度比HttpClient要快。
哪一种方式是最好的?
HttpClient 在 Android 2.2 之前拥有比较少的 bug,因此选择它是最好的选择。
在 Android 2.3 及以后,HttpURLConnection 是最好的选择。它那简单的 API 以及小尺寸使其非常适合 Android。透明的压缩和响应缓存减少了网络的使用,提高速度以及节省电量。新的应用程序中应使用 HttpURLConnection。我们未来也会将更多的精力花在优化 HttpURLConnection 上面。
sqlite插入数据的时候默认一条语句就是一个事务,有多少条数据就有多少次磁盘操作。初始5000条记录也就是要5000次读写磁盘操作, 将会重复的打开关闭数据库文件5000次,所以速度当然会很慢。而且不能保证所有数据都能同时插入。
解决方法:
添加事务处理,把5000条插入作为一个事务
我们使用SQLite的事务进行控制:
db.beginTransaction(); //手动设置开始事务
try{
//批量处理操作
for(Collection c:colls){
insert(db, c);
}
db.setTransactionSuccessful(); //设置事务处理成功,不设置会自动回滚不提交。
//在setTransactionSuccessful和endTransaction之间不进行任何数据库操作
}catch(Exception e){
MyLog.printStackTraceString(e);
}finally{
db.endTransaction(); //处理完成
}
Android广播机制
广播(Broadcast)机制用于进程/线程间通信,广播分为广播发送和广播接收两个过程,其中广播接收者BroadcastReceiver便是Android四大组件之一。
BroadcastReceiver分为两类:
静态广播接收者:通过AndroidManifest.xml的标签来申明的BroadcastReceiver。
动态广播接收者:通过AMS.registerReceiver()方式注册的BroadcastReceiver,动态注册更为灵活,可在不需要时通过unregisterReceiver()取消注册。
从广播发送方式可分为三类:
普通广播:通过Context.sendBroadcast()发送,可并行处理
有序广播:通过Context.sendOrderedBroadcast()发送,串行处理
Sticky广播:通过Context.sendStickyBroadcast()发送,发出的广播会一直滞留(等待),以便有人注册这则广播消息后能尽快的收到这条广播。
Android 中的 Broadcast 实际底层使用Binder机制。
Q:获取Bitmap对象并计算它所占用的内存大小:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.size);
int size = bitmap.getByteCount();
getByteCount()源码:
public final int getByteCount() {
return getRowBytes() * getHeight();
}
getHeight():图片的高度(单位为px), getRowBytes方法返回的是图片的像素宽度与色彩深度的乘积。
所以getByteCount()是这样计算的:像素宽 * 像素高 * 色彩深度,其中色彩深度与Bitmap的色彩格式有关,默认为ARGB_8888.
### 这里补充一个小知识点吧!
ARGB_4444: 2bytes 每个像素占据2 个字节:A(Alpha)占4位的精度,R(Red)占4位的精度,G(Green)占4位的精度,B(Blue)占4位的精度,加起来一共是16位的精度,折合是2个字节,也就是一个像素占两个字节的内存,同时存储位图的透明度和颜色信息。
ARGB_8888 : 4bytes 每个像素占据4 个字节:这个类型的跟ARGB_4444的原理是一样的,只是A,R,G,B各占8个位的精度,所以一个像素占4个字节的内存。由于该类型的位图质量较好,官方特别推荐使用。但是,如果一个480*800的位图设置了此类型,那个它占用的内存空间是:480*800*4/(1024*1024)=1.5M
RGB_565 : 2bytes 每个像素占据2 个字节:R占5位精度,G占6位精度,B占5位精度,一共是16位精度,折合两个字节。这里注意的时,这个类型存储的只是颜色信息,没有透明度信息
Q:为什么不能在子线程中更新UI ?
一般我们在项目中,进行联网请求后,这里我们就用子线程来表示联网请求,开了线程后获取到我们服务器返回的数据后,需要去更新UI,在这里我们就需要去调用setText()、setImageView()、setVisibility()等等等等,不管你调用的什么方法,它都会去调用 ViewRootImpl 中的 checkThread(),所以关键在于checkThread()这个方法
checkThread()方法分析:
1>:checkThread()方法作用是用来检测线程,源码如下:
void checkThread() { if (mThread != Thread.currentThread()) { throw new CalledFromWrongThreadException( "Only the original thread that created a view hierarchy can touch its views."); } }
2>:if (mThread != Thread.currentThread()) 中的 Thread.currentThread()是子线程,而mThread是在构造方法中初始化的 是主线程 [ MainThread ]
如果两个不相等,那么那么左边就是主线程、右边就是子线程;
如果两个相等,那么就是主线程
由上边源码可知:
如果两个相等,就说明两个都是在主线程中,那么就不会调用下边的异常;
如果两个不相等,就说明是在子线程中更新UI,那么就会调用checkThread()方法,就会抛出下边的异常Only the original thread that created a view hierarchy can touch its views.
这个只解释了如果在子线程更新UI为什么会抛异常;真正不能再自在子线程更新UI的原因是:UI控件非线程安全,在多线程中并发访问可能会导致UI控件处于不可预期的状态。而不对UI控件的访问加上锁机制的原因有:
上锁会让UI控件变得复杂和低效
上锁后会阻塞某些进程的执行
2018 最新 Android 面试题总结(一)
2018最新 Android 面试题总结(二)
2018最新 Android 面试题总结(三)
2018最新 算法面试题总结(一)
2018最新 计算机 网络面试题总结(一)
2018最新 java 面试题总结(一)
https://www.jianshu.com/p/399ca1b4e0c3