ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] ## 四大组件 ### Acvitiy #### Activity生命周期 ![](http://ww1.sinaimg.cn/large/c210e9d8ly1g0ihd9xaqhj20sm0yqahs.jpg) * 每一个生命周期对应的过程 * onCreate:Activity正在创建。适合做一些初始化工作,初始化Activity所需要的数据等。 * onStart:Activity正在被启动,即将开始,这时Activity已经可见,但是还没有出现在前台,还无法和用户交互。可以理解为这个时候Activity已经出来了,但是我们还看不到 * onResume:此时Activity已经对用户可见,并且出现在前台开始活动。 * onPause:表示Activity正在停止,正常情况下紧接着onStop就会被调用。此时可以做一些轻量级的操作,不能太耗时。否则会影响到新的Activity的显示,onPause必须先执行完,新Activity的onResume才回执行。 * onStop:表示Activity即将停止,可以做一些稍微重量级的回收工作,同样不能太耗时。 * onDestroy:表示Activity即将呗销毁,这是Activity生命周期中的最后一个回调,在这里可以做一些回收工作和最终的资源释放。 * onRestart:Activity从不可见变为可见状态时调用。 * 常见情况分析 * Activity第一次启动:onCreate->onStart->onResume * 锁屏或者按Home键:onPause->onStop * 解锁:onRestart->onStart->onResume * AActivity启动BActivity(正常Activity):A.onPause->B.onCreate->B.onStart->B.onResume->A.onStop(如果B是透明的,则没有onStop这一步骤) * 按back退出:onPause->onStop->onDestroy * 总结 * onCreate和onDestroy是一对,onStart和onStop是一对,onResume和onPause是一对 #### Activity启动模式分析 如何查看Activity栈: adb shell dumpsys activity ![](http://ww1.sinaimg.cn/large/c210e9d8gy1fzzybc90imj20zk0fnq3o.jpg) * standard模式: 每启动一次Activity,就会创建一个新的Activity实例并置于栈顶。谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity所在的栈中。 例如:Activity A启动了Activity B,则就会在A所在的栈顶压入一个新的Activity。 ![](https://box.kancloud.cn/b480ee0087d81448579bd6e67afb005e_651x335.png) 特殊情况:如果再Service或者Application中启动一个Acitivty,并没有所谓的任务栈,会报错可以使用标记位Flag来解决,为启动的Activity指定FLAG_ACTIVITY_NEW_TASK标记位,创建一个新栈。 * singletop模式: 在这个模式中,Activity还是会创建在启动它的Activity的任务栈中,但是如果它已经位于栈顶,那么就不会重复创建,并且它的onNewIntent会被调用,但是要注意它的生命周期方法onCreate等等不会创建。并且如果它并不位于栈顶,如ABC,这时启动B,还是会创建一个新的实例。 * singletask模式: 在这个模式中,比如启动Activity A,首先系统会寻找是否存在A想要的任务栈: 如果存在,就看任务栈中是否有A,如果有就有clearTop的效果,把A推到栈顶,并且调用onNewIntent,即CABD的任务栈,clearTop之后就是CA;如果没有A,就创建A在栈顶。并且要注意一点,如果存在A的任务栈,那么任务栈自动回切换到前台,如下图所示: ![](https://box.kancloud.cn/663f93476ddb6f52df47565b37e8d560_550x309.png) Y的任务栈直接被切换到了前台,这点和微信的聊天界面是一样的。 如果不存在,就创建A所需要的任务栈并且创建A入栈。 **使用场景:** 一般来说栈内复用适用于在一个应用里我们希望唯一存在的界面,比如聊天界面,比如微信的聊天界面,我们在一个聊天界面点击了头像进入了新的界面,这个时候来了一条新的消息并且用户点击了消息,这个时候如果是Standard模式就会创建一个新的实例,这样用户在新的界面点击back,用户期望回到的是主界面,而实际上回到了之前的头像界面,这就不符合常规了。如果把聊天设为栈内唯一模式,那么用户点击之后就会回到之前的聊天界面并且做一些改变,保证了聊天界面的唯一性。浏览器的例子也是这样,我们肯定希望浏览器浏览的界面是唯一的,也需要用到这个模式。 **TaskAffinity:**https://juejin.im/post/5935081d2f301e006b09cb9e * singleInstance模式: 单实例模式。启动的时候无论从哪里启动都会创建一个唯一的任务栈,后续的创建都不会再创建新的Activity继续复用该Activity同时回调onNewIntent方法,除非该Activity被销毁了。 singleInstace与singleTask的区别在于:singleTask启动的Activity在系统层面上来说是可以有多个实例的。比如说应用程序A想调用singleTask模式下的ActivityA,而应用程序B也同样调用了,那么在应用程序A和B中就会各有一个ActivityA的实例。但如果该ActivityA是singleInstance模式的话,那么无论有多少个应用程序调用它,它都只可能在系统中存在一个实例同时该实例还是位于它自己的一个单独的任务栈中。 ![](https://box.kancloud.cn/f5a5b6b794c1bbcff11a6b74769b4935_713x386.png) **应用场景:**呼叫来电界面。这种模式的使用情况比较罕见,在Launcher中可能使用。或者你确定你需要使Activity只有一个实例。建议谨慎使用。 #### Activity启动流程 [3分钟看懂Activity启动流程](https://www.jianshu.com/p/9ecea420eb52) ![](https://box.kancloud.cn/65ce1abf2ba1a94c9f13ef054164ae41_3881x2715.png) 整个流程涉及的主要角色有: * Instrumentation: 监控应用与系统相关的交互行为。 * AMS:组件管理调度中心,什么都不干,但是什么都管。 * ActivityStarter:Activity启动的控制器,处理Intent与Flag对Activity启动的影响,具体说来有:1 寻找符合启动条件的Activity,如果有多个,让用户选择;2 校验启动参数的合法性;3 返回int参数,代表Activity是否启动成功。 * ActivityStackSupervisior:这个类的作用你从它的名字就可以看出来,它用来管理任务栈。 * ActivityStack:用来管理任务栈里的Activity。 * ActivityThread:最终干活的人,是ActivityThread的内部类,Activity、Service、BroadcastReceiver的启动、切换、调度等各种操作都在这个类里完成。 注:这里单独提一下ActivityStackSupervisior,这是高版本才有的类,它用来管理多个ActivityStack,早期的版本只有一个ActivityStack对应着手机屏幕,后来高版本支持多屏以后,就 有了多个ActivityStack,于是就引入了ActivityStackSupervisior用来管理多个ActivityStack。 整个流程主要涉及四个进程: * 调用者进程,如果是在桌面启动应用就是Launcher应用进程。 * ActivityManagerService等所在的System Server进程,该进程主要运行着系统服务组件。 * Zygote进程,该进程主要用来fork新进程。 * 新启动的应用进程,该进程就是用来承载应用运行的进程了,它也是应用的主线程(新创建的进程就是主线程),处理组件生命周期、界面绘制等相关事情。 有了以上的理解,整个流程可以概括如下: 1. 点击桌面应用图标,Launcher进程将启动Activity(MainActivity)的请求以Binder的方式发送给了AMS。 2. AMS接收到启动请求后,交付ActivityStarter处理Intent和Flag等信息,然后再交给ActivityStackSupervisior/ActivityStack 处理Activity进栈相关流程。同时以Socket方式请求Zygote进程fork新进程。 3. Zygote接收到新进程创建请求后fork出新进程。 4. 在新进程里创建ActivityThread对象,新创建的进程就是应用的主线程,在主线程里开启Looper消息循环,开始处理创建Activity。 5. ActivityThread利用ClassLoader去加载Activity、创建Activity实例,并回调Activity的onCreate()方法。这样便完成了Activity的启动。 ### AMS是怎么找到启动的那个activity的? #### 保存Activity的状态以及onSaveInstanceState原理分析 [Android状态保存与恢复流程完全解析](https://mp.weixin.qq.com/s?src=11&timestamp=1548662220&ver=1393&signature=xOmN4*hyWgvJrBnpgnLhoImzDuEKdrGoNnHIibhN-R*7pxpaGdGmeJyZNno4clTGYZr7T0SjNJ7xheUdKE0hNwT2vjtlmX8ZAEZ-soXGae9JmTZ0iaFbRktSmA2N9Fsq&new=1) ### Serivce #### Service生命周期(注意bindService和startService之间生命周期的不同) * (1)startService() ![](http://ww1.sinaimg.cn/large/c210e9d8ly1g0ihcmdgc9j20u007v757.jpg) * (2)stopService() ![](https://box.kancloud.cn/bc9eb23445a3e9dfde1003ae40a1e56e_1170x353.png) * (3)bindService() ![](https://box.kancloud.cn/32821eba90956a4e4b1addd2bcbaec7f_1234x227.png) * (4)unbindService() ![](https://box.kancloud.cn/b67c73b258af8380de732abbea795004_1240x234.png) * (5)只使用startService启动服务的生命周期 ![](https://box.kancloud.cn/4de9dcad82833e732dbb235cc3faddc3_1240x120.png) * (6)只使用BindService绑定生命周期服务 ![](https://box.kancloud.cn/2d4514a3837e19245440d217b6136ff4_1240x107.png) * (7)同时使用startService()启动服务、BindService()绑定服务的生命周期 ![](https://box.kancloud.cn/166da066cd1f5ad1c3851fb0571b4c48_1240x74.png) #### Service先start再bind如何关闭service,为什么bindService可以跟Activity生命周期联动? #### Service 与 IntentService 的区别 #### Activity如何与Service通信? ### BroadCast #### 广播分为哪几种,应用场景是什么? * 普通广播 即开发者自身定义intent的广播(最常用) * 系统广播 Android系统内置的广播,例如开机、网络状态变化等都会发出响应广播,这些广播都有对应的intent-filter。 * 有序广播 * 1.按照Priority属性值从大到小排序 * 2.Priority属性相同者,动态注册的广播优先。 接收广播按顺序接收。先接收的广播接受者可以对广播进行截断,即后接受的广播接受者不再接收此广播。同时先接收的广播可以对广播进行修改,后接受的广播接受者接受到的就是修改后的广播。 * 粘性广播 Android5.0中已经失效,不建议使用。 * App应用内广播 Android中的广播可以跨App直接通信(exported对于有intent-filter情况下默认值为true),这样会导致其他App针对性发出当前App相匹配的广播,导致当前App不断接受广播并处理出现安全性、效率问题。 应用内广播(LocalBroadcast)可以理解成为一种局部广播,广播的发送者和接受者都只能是当前App,这样使得广播的安全性以及效率更高。 #### 广播的两种注册方式有什么区别? * 1.代码中动态注册 * 2.在Manifest.xml中静态注册 第一种不是常驻型广播,也就是说广播跟随程序的生命周期。第二种是常驻型,也就是说程序关闭后,如果有信息广播来,程序也会被系统调用运行。 #### 广播发送和接收的原理了解吗? Android中的广播使用了设计模式中的观察者模式,基于消息的发布/订阅事件模型。 具体实现流程概括如下: - 1.自定义广播接受者BroadcastReceiver,并复写onReceive()方法 - 2.通过Binder机制向AMS进行注册 - 3.广播发送者通过Binder机制向AMS发送广播 - 4.AMS查找复合相应条件(IntentFilter/Permission等)的BroadcastReceiver,将广播发送到BroadcastReceiver相应的消息循环队列中。 - 5.消息循环执行拿到此广播,回调BroadcastReceiver中的onReceive()方法 #### 广播传输的数据是否有限制,是多少,为什么要限制? 广播是通过Intent携带要传递的数据的。Intent是通过Binder机制实现的,Binder对数据大小有限制,不同ROM不一样,一般是1M。Binder在通信过程当中,会发生一次内存拷贝,显示,传输的数据越小效率越高。 #### BroadcastReceiver与LocalBroadcastReceiver有什么区别? * BroadcastReceiver是跨应用广播,利用Binder机制实现。 * LocalBroadCastReceiver是应用内广播,利用Handler实现,利用了IntentFilter的match功能,提供消息的发布与接收功能,实现应用内通信,效率较高。 ### 跨域广播也是观察者模式吗? ### 两个应用同时注册一个广播,优先级都一样,哪个会先收到广播?(有序广播?) ### ContentProvider #### ContentProvider、ContentResolver与ContentObserver之间的关系是什么? ### contenprovider已经是进程间通信,为什么还要引入broadcastreceiver? ## Fragment ### Fragment生命周期 [Fragments: The Solution to All of Android's Problems](https://academy.realm.io/posts/michael-yotive-state-of-fragments-2017/) [Android基础:Fragment,看这篇就够了](https://cloud.tencent.com/developer/article/1071779) [我为什么主张反对使用Android Fragment](https://asce1885.gitbooks.io/android-rd-senior-advanced/content/wo_wei_shi_yao_zhu_zhang_fan_dui_shi_yong_android_fragment.html) ![Fragment生命周期](http://ww1.sinaimg.cn/large/c210e9d8ly1fzmf9mikjnj20b409uglm.jpg) ![Fragment生命周期](http://ww1.sinaimg.cn/large/c210e9d8ly1fzmeytd111j20hs0l43z9.jpg) ### getActivity()空指针问题 ### Fragment视图重叠 ### Fragment之间如何通信 ### Fragment 和 Activity 有什么区别?它们之间又有什么关系? ## View ### View绘制流程 [Android View的绘制流程](https://jsonchao.github.io/2018/10/28/Android%20View%E7%9A%84%E7%BB%98%E5%88%B6%E6%B5%81%E7%A8%8B/) [Android应用层View绘制流程与源码分析](https://blog.csdn.net/yanbober/article/details/46128379) [浅析Android View内部工作原理及其实战](https://blog.csdn.net/AndrExpert/article/details/77511996) ### 描述一下Android的事件分发机制? [Android触摸事件传递机制](https://jsonchao.github.io/2018/10/17/Android%E8%A7%A6%E6%91%B8%E4%BA%8B%E4%BB%B6%E4%BC%A0%E9%80%92%E6%9C%BA%E5%88%B6/) [【透镜系列】看穿 > 触摸事件分发 >](https://juejin.im/post/5c3c8538f265da6142741d63) [Android事件分发机制学习笔记](https://zhuanlan.zhihu.com/p/27608989) [可能是讲解Android事件分发最好的文章](https://www.jianshu.com/p/2be492c1df96) ### 计算viewgroup的层级,递归实现和非递归实现 ### 在onCreate里面可以得到view的宽高吗? ### view的getWidth和getMeasureWidth有啥区别? ### Scroller使用原理 ### 动画有哪几类,各有什么特点 * 视图动画(View 动画) * 帧动画(Frame 动画、Drawable 动画) * 属性动画 * 触摸反馈动画(Ripple Effect) * 揭露动画(Reveal Effect) * 转场动画 & 共享元素(Activity 切换动画) * 视图状态动画(Animate View State Changes) * 矢量图动画(Vector 动画) * 约束布局实现的关键帧动画(ConstraintSet 动画) [Android 一共有多少种动画?准确告诉你!](https://www.jianshu.com/p/0eb89d43eea4) ### PopupWindow和Dialog的区别 ### Activity、Window、View的关系 ![](http://ww1.sinaimg.cn/large/c210e9d8ly1g0gdzi0nc8j20iy0pmq31.jpg) [Activity、View、Window的理解一篇文章就够了](https://juejin.im/entry/596329686fb9a06bc903b6fd) [Android视图框架Activity,Window,View,ViewRootImpl理解](https://silencedut.github.io/2016/08/10/Android%E8%A7%86%E5%9B%BE%E6%A1%86%E6%9E%B6Activity,Window,View,ViewRootImpl%E7%90%86%E8%A7%A3/) ### 一个下拉刷新界面的实现原理 ### 什么是 ViewGroup ,它与 View 的区别在哪里? ### RecyclerView的复用原理 ### RecyclerView缓存机制相比ListView缓存机制有啥改进 ### 你知道什么是视图树(View Tree)吗?怎样优化它的深度? ### viewpager嵌套滑动冲突怎么解决 ### 介绍一下svg动画 [Android SVG矢量动画机制](https://www.jianshu.com/p/47b0ae970dd5) SVG动画是在android5.X才引入(需要考虑兼容性问题) ## 动画 ### 补间动画常见的效果?有哪几个常见的插入器? ### 补间动画click事件还在原位怎么解决? ## 布局 ### android:gravity和android:layout_gravity的区别? ### 解释layout_weight的作用 ### android常用布局以及排版效率 ### 约束布局的原理以及与相对布局之间的区别 ### 布局怎么做到每行的文字左右对齐? [不到100行代码实现左右对齐TextView](https://www.jianshu.com/p/7241ed34346a) ## WebView相关 ### 系统进程可以用webview吗? ### WebView优化了解吗,如何提高WebView的加载速度? ### Java和JS的相互调用怎么实现,有做过什么优化吗? ## 编译打包 ### APK打包流程 ![](http://ww1.sinaimg.cn/large/c210e9d8ly1g0ihakjobrj20qe0toah5.jpg) ![](http://ww1.sinaimg.cn/large/c210e9d8ly1g0ihb83lolj20ew0oitch.jpg) Android打包流程总共七步: (1)通过aapt打包res资源文件,生成R.java、resources.arsc和res文件(二进制 & 非二进制如res/raw和pic保持原样) (2)处理.aidl文件,生成对应的Java接口文件 (3)通过Java Compiler编译R.java、Java接口文件、Java源文件,生成.class文件 (4)通过dex命令,将.class文件和第三方库中的.class文件处理生成classes.dex (5)通过apkbuilder工具,将aapt生成的resources.arsc和res文件、assets文件和classes.dex一起打包生成apk (6)通过Jarsigner工具,对上面的apk进行debug或release签名 (7)如果是正式版的APK,会利用ZipAlign工具进行对齐处理,对齐过程就是将APK文件中所有的资源文件距离文件的起始距离都偏移4字节的整数倍,这样通过内存映射都偏移4字节的整数倍,这样通过内存映射访问APK文件速度会更快。 ![](http://ww1.sinaimg.cn/large/c210e9d8ly1g0ihbvfow4j20rl0u3n99.jpg) ### 如何进行多渠道打包 ### APK安装流程 ### 什么是 AAPT ? ### transform api ### 如何反编译APP ## Android消息机制 ### Android Handler机制是做什么的,原理了解吗? ![](https://box.kancloud.cn/ea9b768545065ee14a3d37ccc196a53d_2286x714.png) [你真应该再多了解些Handler机制](https://www.jianshu.com/p/8862bd2b6a29) [Handler后传篇一: 为什么Looper中的Loop()方法不能导致主线程卡死?](https://juejin.im/post/5c5694b951882562e5441e71?utm_source=gold_browser_extension) ### Android Binder机制是做什么的,为什么选用Binder,原理了解吗? * [为什么 Android 要采用 Binder 作为 IPC 机制?](https://www.zhihu.com/question/39440766) ### 介绍下 AIDL 的原理 ## Android架构相关 ### 什么是MVC ### 什么是MVP ### 什么是MVVM ### MVC、MVP以及MVVM的区别 ### AAC架构 ### ## 数据库 ### 常用开源数据库框架介绍及实现原理 ### 隔代数据库升级 ## 性能优化 ### 性能优化的工具使用 ### 内存优化(如何避免OOM) [管理应用的内存](https://github.com/kesenhoo/android-training-course-in-chinese/blob/master/performance/memory.md) [Android 内存管理机制](https://juejin.im/entry/589ff0d22f301e00694acbb3) [Android内存管理](https://zhuanlan.zhihu.com/p/38025941) ### 渲染优化 #### 如何得到activity绘制完UI界面的时间 ### 电量优化 ### 体积优化 ### ANR优化 ## Bitmap相关 ### Bitmap优化 [探索Bitmap使用姿势](https://juejin.im/post/5c56bd57f265da2dc5388f33?utm_source=gold_browser_extension) [Bitmap优化详谈](https://juejin.im/post/5bfbd5406fb9a049be5d2a20) ### 如何加载一张大图 * Android如何在不压缩的情况下加载高清大图? ### Bitmap有几种格式?一个像素分别占多少字节 * 如何计算一个Bitmap占用内存的大小,怎么保证加载Bitmap不产生内存溢出? ### ## 其他 ### 如何理解严格模式(StrictMode) 严格模式是用来检测程序中违例情况情况的开发者工具。最常用的场景就是检查主线程中本地磁盘和网络读写等耗时操作。使用严格模式,系统检测出主线程违例的情况会做出相应的反应,如日志打印,弹出对话框亦或者崩溃等。换言之,严格模式会将应用的违例细节暴露给开发者方便优化与改善。 严格模式主要检测两大类问题,一个是线程策略即TreadPolicy,另一个是VM策略,即VmPolicy。 VmPolicy: - Activity泄露 使用**detectActivityLeaks()**开启 - 未关闭的Closable对象泄露 使用**detectLeakedClosableObjects()**开启 - 泄露的Sqlite对象 使用**detectLeakedSqlLiteObjects()**开启 - 检测实例数量 使用**setClassInstanceLimit()**开启 TreadPolicy: - 自定义的耗时调用 使用**detectCustomSlowCalls()**开启 - 磁盘读取操作 使用**detectDiskReads()**开启 - 磁盘写入操作 使用**detectDiskWrites()**开启 - 网络操作 使用**detectNetwork()**开启 [Android性能调优利器StrictMode](https://droidyue.com/blog/2015/09/26/android-tuning-tool-strictmode/) ### Android里的内存缓存和磁盘缓存是怎么实现的。 ### SharePreference性能优化,可以做进程同步吗? ### assets与res/raw的区别? ## Android多线程与多进程 ### 解释一下 AsyncTask及其原理 ### AsyncTask 的生命周期和(它所属的) Activity 的生命周期有什么关系?这种关系可能会导致什么样的问题? 如何避免这些问题发生? ### 操作系统中进程与县城有什么联系和区别,系统什么时候回在用户态和内核态中切换? ### Binder的原理?为什么要使用Binder?与Linux和Windows之间进程通讯的区别? ### ThreadLocal的原理 [ThreadLocal必知必会(基于JDK1.8)](https://mp.weixin.qq.com/s/AB4DF_b2t5lllmeuLH1GmQ) ## 其他 ### 什么是9patch图 [.9.png,全面认识“点九图”](https://zhuanlan.zhihu.com/p/29217200) > 点九图是一种可拉伸的位图,安卓会自动调整它的大小,来使图像在充当背景时可以在界面中自适应。点九图的一个典型使用场景,就是用作标准Android按钮的背景图,因为按钮必须通过拉伸,来适应不同程度的字符。 点九图是标准PNG格式的图像,并且包含了多出来的1像素宽的边界。保存点九图时要以”.9.png”为结尾,放置在项目中“res/drawable/”的路径之下。 四个黑边代表什么含义? * 上边线:图像横向可拉伸的部分 * 左边线:图像纵向可拉伸的部分 * 右边线:图像纵向可填充内容(文字或图片)区域 * 下边线:图像横向可填充内容(文字或图片)区域 ### 什么是Context,Android有多少种Context 从Android系统的角度来理解:Context是一个场景,代表与操作系统的交互的一种过程。Context在加载资源、启动Activity、获取系统服务、创建View等操作都要参与 。从程序的角度上来理解:Context是个抽象类,而Activity、Service、Application等都是该类的一个实现。 ![](http://ww1.sinaimg.cn/large/c210e9d8ly1g0hls6dywij20hr0ci0so.jpg) ### JSON有什么优劣势、解析的原理以及与XML之间的对比 > JSON是一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。业内主流技术为其提供了完整的解决方案(有点类似于正则表达式 ,获得了当今大部分语言的支持),从而可以在不同平台间进行数据交换。JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为。 **JSON 和 XML 优缺点的比较**  * 1.在可读性方面,JSON和XML的数据可读性基本相同。JSON和XML的可读性可谓不相上下,一边是建议的语法,一边是规范的标签形式,很难分出胜负。  * 2.在可扩展性方面,XML天生有很好的扩展性,JSON当然也有,没有什么是XML能扩展,JSON不能的。  * 3.在编码难度方面,XML有丰富的编码工具,比如Dom4j、JDom等,JSON也有json.org提供的工具,但是JSON的编码明显比XML容易许多,即使不借助工具也能写出JSON的代码,可是要写好XML就不太容易了。  * 4.在解码难度方面,XML的解析得考虑子节点父节点,让人头昏眼花,而JSON的解析难度几乎为0。这一点XML输的真是没话说。  * 5.在流行度方面,XML已经被业界广泛的使用,而JSON才刚刚开始,但是在Ajax这个特定的领域,未来的发展一定是XML让位于JSON。到时Ajax应该变成Ajaj(Asynchronous JavaScript and JSON)了。  * 6.JSON和XML同样拥有丰富的解析手段。  * 7.JSON相对于XML来讲,数据的体积小。 * 8.JSON与JavaScript的交互更加方便。 * 9.JSON对数据的描述性比XML较差。 * 10.JSON的速度要远远快于XML。 ### 理解序列化吗,Android为什么引入Parcelable? 所谓序列化就是将对象变成二进制流,便于存储和传输。 - Serializable是java实现的一套序列化方式,可能会触发频繁的IO操作,效率比较低,适合将对象存储到磁盘上的情况。 - Parcelable是Android提供一套序列化机制,它将序列化后的字节流写入到一个共性内存中,其他对象可以从这块共享内存中读出字节流,并反序列化成对象。因此效率比较高,适合在对象间或者进程间传递信息。 ### 介绍Serializable和Parcelable的使用方法以及区别 * 1.实现Serializable接口需要添加serialVersionUID,不添加不会影响使用。UID在序列化的时候回写入文件,反序列化的时候回读取这个UID,并与反序列化中类的UID进行对比。如果相同则反序列化成功,不相同则反序列化失败。当不指定UI的时候,系统会根据类的结构生成相应的hash赋值给UID,但是当类发生变化的时候UID就会发生变化,这样会导致反序列化失败。添加UID可以减少反序列化失败的几率。(但是当类发生了非常规的结构变化,如类名、成员变量类型变化,就算指定了UID,反序列化也会失败)。 同时静态类型变量不属于对象,不会参与序列化过程;用transient关键字标记的成员变量不参与序列化过程。 * Parcelable接口各方法含义 ![](http://ww1.sinaimg.cn/large/c210e9d8ly1g0hkf0wpodj20jg07zt8v.jpg) **区别** * 1.存储媒介不同:Serializable使用 I/O 读写存储在硬盘上,而Parcelable是直接在内存中读写。内存的读写速度通常大于I/O,所以在Android中传递数据有限使用Parcelable。 * 2.Serializable会使用反射,序列化和反序列化过程需要大量I/O操作,Parcelable自己实现封送和解封操作不需要使用反射,数据也存放在Native内存中,效率高很多。 ![](http://ww1.sinaimg.cn/large/c210e9d8ly1g0hlgm0h74j20go09fjrb.jpg) ### ### Lint静态代码检查 参考Lint专栏 ### 为什么 Bundle 被用来传递数据,为什么不能使用简单的 Map 数据结构? ### 屏幕适配相关 * 修改系统density值系列 [骚年你的屏幕适配方式该升级了!-今日头条适配方案](https://mp.weixin.qq.com/s/oSBUA7QKMWZURm1AHMyubA) [一种极低成本的Android屏幕适配方式](https://mp.weixin.qq.com/s?__biz=MzI1MzYzMjE0MQ==&mid=2247484502&idx=2&sn=a60ea223de4171dd2022bc2c71e09351&scene=21#wechat_redirect) 总结:头条修改density方案是通过实际屏幕宽度/高度(px单位)/ 设计图宽度/高度(dp单位)重新计算出一个density值来进行适配。 * 限制适配符方案 [Android 目前稳定高效的UI适配方案](https://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650826034&idx=1&sn=5e86768d7abc1850b057941cdd003927&chksm=80b7b1acb7c038ba8912b9a09f7e0d41eef13ec0cea19462e47c4e4fe6a08ab760fec864c777&scene=21#wechat_redirect) [骚年你的屏幕适配方式该升级了!-smallestWidth 限定符适配方案](https://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650826381&idx=1&sn=5b71b7f1654b04a55fca25b0e90a4433&chksm=80b7b213b7c03b0598f6014bfa2f7de12e1f32ca9f7b7fc49a2cf0f96440e4a7897d45c788fb&scene=21#wechat_redirect) ### app闪退的原因有哪些?每种情况简述一下分析过程 ### 解析xml有哪几种方式,优缺点分别是什么? ### 自己写一个应用,包名就叫android行不行,为什么? ## Android系统新特性 ### 权限管理 ## Android虚拟机相关 ### 字节码 [一起玩转Android项目中的字节码](http://quinnchen.me/2018/09/13/2018-09-13-asm-transform/) ### 什么是 Dalvik 虚拟机? 参考:[简单理解Android Dalvik、ART及APK编译过程](https://www.jianshu.com/p/92227738f270) Dalvik是Google公司自己设计用于Android平台的Java虚拟机,它是Android平台的重要组成部分,支持dex格式(Dalvik Executable)的Java应用程序的运行。dex格式是专门为Dalvik设计的一种压缩格式,适合内存和处理器速度有限的系统。Google对其进行了特定的优化,使得Dalvik具有高效、简洁、节省资源的特点。从Android系统架构图知,Dalvik虚拟机运行在Android的运行时库层。 Dalvik作为面向Linux、为嵌入式操作系统设计的虚拟机,主要负责完成对象生命周期管理、堆栈管理、线程管理、安全和异常管理,以及垃圾回收等。另外,Dalvik早期并没有JIT编译器,直到Android2.2才加入了对JIT的技术支持。 ### Dalvik虚拟机的特点 * 体积小,占用内存空间小; * 专有的DEX可执行文件格式,体积更小,执行速度更快; * 常量池采用32位索引值,寻址类方法名,字段名,常量更快; * 基于寄存器架构,并拥有一套完整的指令系统; * 提供了对象生命周期管理,堆栈管理,线程管理,安全和异常管理以及垃圾回收等重要功能; * 所有的Android程序都运行在Android系统进程里,每个进程对应着一个Dalvik虚拟机实例。 ### Dalvik虚拟机与Java虚拟机的区别 * Java虚拟机运行的是Java字节码,Dalvik虚拟机运行的是Dalvik字节码 传统的Java程序经过编译,生成Java字节码保存在class文件中,Java虚拟机通过解码class文件中的内容来运行程序。而Dalvik虚拟机运行的是Dalvik字节码,所有的Dalvik字节码由Java字节码转换而来,并被打包到一个DEX(Dalvik Executable)可执行文件中。Dalvik虚拟机通过解释DEX文件来执行这些字节码。 ![](http://ww1.sinaimg.cn/large/c210e9d8ly1g0itg8b64hj20a10c8a9w.jpg) * Dalvik可执行文件体积小。Android SDK中有一个叫dx的工具负责将Java字节码转换为Dalvik字节码 dx工具对Java类文件重新排列,消除在类文件中出现的所有冗余信息,避免虚拟机在初始化时出现反复的文件加载与解析过程。一般情况下,Java类文件中包含多个不同的方法签名,如果其他的类文件引用该类文件中的方法,方法签名也会被复制到其类文件中,也就是说,多个不同的类会同时包含相同的方法签名,同样地,大量的字符串常量在多个类文件中也被重复使用。这些冗余信息会直接增加文件的体积,同时也会严重影响虚拟机解析文件的效率。消除其中的冗余信息,重新组合形成一个常量池,所有的类文件共享同一个常量池。由于dx工具对常量池的压缩,使得相同的字符串,常量在DEX文件中只出现一次,从而减小了文件的体积。 针对每个Class文件,都由如下格式进行组成: ![](http://ww1.sinaimg.cn/large/c210e9d8ly1g0itli6bqqj20gz0cj74x.jpg) dex格式文件使用共享的、特定类型的常量池机制来节省内存。常量池存储类中的所有字面常量,它包括字符串常量、字段常量等值。总的来说,dex格式文件就是将多个class文件中公有的部分统一存放,去除冗余信息。 ![](http://ww1.sinaimg.cn/large/c210e9d8ly1g0itm1m2ysj20mj0eg0t6.jpg) * Java虚拟机与Dalvik虚拟机架构不同。这也是Dalvik与JVM之间最大的区别。**Java虚拟机基于栈架构**,程序在运行时虚拟机需要频繁的从栈上读取或写入数据,这个过程需要更多的指令分派与内存访问次数,会耗费不少CPU时间,对于像手机设备资源有限的设备来说,这是相当大的一笔开销。**Dalvik虚拟机基于寄存器架构**。数据的访问通过寄存器间直接传递,这样的访问方式比基于栈方式要快很多。 ### Dalvik虚拟机结构 ![](http://ww1.sinaimg.cn/large/c210e9d8ly1g0itnvexw6j208y0dsa9z.jpg) 一个应用首先经过DX工具将class文件转换成Dalvik虚拟机可以执行的dex文件,然后由类加载器加载原生类和Java类,接着由解释器根据指令集对Dalvik字节码进行解释、执行。最后,根据dvm_arch参数选择编译的目标机体系结构。 ### 什么是ART ART代表Android Runtime,其处理应用程序执行的方式完全不同于Dalvik,Dalvik是依靠一个Just-In-Time (JIT)编译器去解释字节码。开发者编译后的应用代码需要通过一个解释器在用户的设备上运行,这一机制并不高效,但让应用能更容易在不同硬件和架构上运 行。ART则完全改变了这套做法,在应用安装时就预编译字节码到机器语言,这一机制叫Ahead-Of-Time (AOT)编译。在移除解释代码这一过程后,应用程序执行将更有效率,启动更快。 * 优点: * 系统性能的显著提升。 * 应用启动更快、运行更快、体验更流畅、触感反馈更及时。 * 更长的电池续航能力。 * 支持更低的硬件。 * 缺点: * 更大的存储空间占用,可能会增加10%-20%。 * 更长的应用安装时间 ### Dalvik 虚拟机模式和 ART(Android Runtime)虚拟机模式的区别 [ART 和 Dalvik](https://source.android.com/devices/tech/dalvik) [Android GC机制实践调研](https://lizhaoxuan.github.io/2016/02/17/androidgcdiaoyan/) * Dalvik虚拟机是在4.4以及以下系统使用,ART虚拟机在Android4.4以上使用 * Dalvik采用JIT(Just In Time Compiler)技术,ART使用AOT(Ahead Of Time)技术 * 垃圾回收方面的区别: * dalvik gc总共有四个过程 * 1.当gc被触发时候,其会去查找所有活动的对象,这个时候整个程序与虚拟机内部的所有线程就会挂起,这样目的是在较少的堆栈里找到所引用的对象.需要注意的是这个回收动作是和应用程序**同时执行(非并发)**. * 2.gc对符合条件的对象进行标记 * 3.gc对标记的对象进行回收 * 4.恢复所有线程的执行现场继续运行 ![](http://ww1.sinaimg.cn/large/c210e9d8ly1g0j0b7xdlkj21hm0v6k55.jpg) dalvik这么做的好处是,当pause之后,gc势必是相当快速的,但是如果出现gc频繁并且内存赤金势必会导致UI卡顿,掉帧、操作不流畅等。art改善了这种gc方式,主要的改善点在其非并发过程改变成了部分并发,还有就是对内存的重新分配管理。 dalvik采用的标记-清除(Mark and Sweep)算法会导致内存碎片化特别严重,每次gc后内存千疮百孔,本来连续的内存块变得碎片化特别严重,之后再进入的对象再进行内存寻址变得十分困难。 当art gc发生时: * 1.gc将会锁住java堆,扫描并进行标记 * 2.标记完毕释放掉java堆的锁,并且挂起所有线程 * 3.gc对标记的对象进行回收 * 4.恢复所有线程的执行现场继续运行 * 5.重复2-4直到结束 可以看出整个过程做到了部分并发使得时间缩短.据官方测试数据说gc效率提高2倍 内存碎片问题上,在art中,它将java分了一块空间命名为**Large-Object-Space**,这块内存空间的引入用来专门存放large object.同时art又引入了moving collector的技术,即将不连续的物理内存块进行对齐.对齐了后内存碎片化就得到了很好的解决.Large-Object-Space的引入一是因为moving collector对大块内存的位移时间成本太高,而且提高内存的利用率。 [Dalvik虚拟机和ART(Android RunTime)的区别](https://blog.csdn.net/lixpjita39/article/details/73058020) ### Android类加载机制流程 [Android虚拟机框架:类加载机制](https://juejin.im/post/5a686596f265da3e2d339bb4) [Android类加载器ClassLoader](http://gityuan.com/2017/03/19/android-classloader/) ### PathClassLoader与DexClassLoader有什么区别? * PathClassLoader: 主要用于系统和app的类加载器,其中optimizedDirectory为null, 采用默认目录/data/dalvik-cache/ * DexClassLoader: 可以从包含classes.dex的jar或者apk中,加载类的类加载器, 可用于执行动态加载, 但必须是app私有可写目录来缓存odex文件. 能够加载系统没有安装的apk或者jar文件,因此很多插件化方案都是采用DexClassLoader; ### 描述一下类加载机制以及其原理在热修复当中的应用 ## Android经典代码分析 ### layoutinflater分析 [LayoutInflater源码分析](https://bboylin.github.io/2018/12/21/LayoutInflater%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/) ### ArrayMap分析 ## NDK相关 ### 如何加载ndk库?如何在jni中注册native函数,有几种注册方式? ### 在android中,请简述jni的调用过程