1.Activity生命周期:
正常流程:onCreate()->onStart()->onResume()->onpause()->onStop()->onDestory();
再次点击回到Activity:onRestart()->onStart()->onResume()
android面试(2)-Activity篇
2.service生命周期:
(1)通过startService()启动:
startService()->onCreate()->onStartCommon()->onDestory();
tips:startService()调用多次,onCreate只会执行一次,onStartCommon调用多次;
调用stopService(),onDestory()执行,销毁服务;
通过intent传值时,必须判null
(2)通过bindService()启动:
bindService()->onCreate()->onBind()->unBind()->onDestory()
android面试(3)-Service篇
3.Activity启动过程:
Launcher调用startActivitySafely()->PMS对AndroidManifest.xml文件进行解析,获取应用程序的相关信息(service,broadcast等)和要启动的Activity的配置信息(action,category等)->调用startActivity()->内部调用startActivityForResult()直接返回-1,表示不需要返回结果;->调用Instrumentation类的execStartActivity()获取AMS的代理对象,通过代理对象->调用checkStartActivityResult()方法,如果没有在配置清单中配置这个组件,这个方法会抛出异常;->调用application的scheduleLaunchActivity()获取一个ActivityClientRecord对象,其中保存这LoaderApk对象->调用handleLaunchActivity启动Activity组件;
4.Broadcast注册方式与区别:
(1)静态注册:
特点:不受页面的生命周期影响,即退出了页面,也可以接收到广播,会占用cpu资源,一般用于想开机自启动等等场景;
(2)动态注册:
特点:会受页面的生命周期影响,即退出页面,不会接收到广播,其优先级较高,一般用于通知UI更新;
5.HttpClient和HttpUrlConnection的区别:
HttpClient的api很多,但是不易扩展,所以在6.0时已经废弃;
HttpUrlConnection比较轻量级,易扩展;
6.Java虚拟机与Dalvik虚拟机区别:
Java虚拟机:
特点:基于栈,使用指令来载入和操作栈上数据,所需指令更多,并且运行的是Java字节码
Dalvik虚拟机:
特点:基于寄存器,运行.dex字节码格式,常量池被修改为只使用32位所有,
一个应用,一个虚拟机实例,一个进程,每个dalvik应用程序都被赋予了一个独立的进程号
7.进程保活:
(1)黑色保活:不同的app进程,用广播相互唤醒(包括利用系统广播进行唤醒)
例1:开机,网络切换,拍照,拍视频等,利用系统产生的广播进行唤醒;
例2:接入第三方sdk也会唤醒相应的app进程;(比如启动支付宝,可能就会把淘宝唤醒)
(2)白色保活:启动前台Service
调用系统的api启动一个前台的Service进程
(3)灰色保活:利用系统漏洞启动一个前台的service:
实现思路:api<18时,启动前台Service时直接传入new Notification();
api>=18时,同时启动两个id相同的前台Service,然后再将后启动的Service做stop处理;
8.关于Context:提供一些程序的运行环境基础信息;
两个子类:
(1)ContextWrapper是Context的封装类,其下又有三个子类,就是我们熟知的Application,service和ContextThemeWrapper,ContextThemeWrapper是一个带主题的封装类,这个可能不熟悉,但是Activity就是继承它的,所以总结的来说,Context有三种类型,分别是Application,Service和Activity,绝大多数情况下都可以通用,但是少数情况下不能通用,Android是不允许Activity或Dialog凭空出现,一个Activity的启动必须要建立在另一个Activity的基础之上,而Dialog则必须在一个Activity上面弹出,所以,当启动Activity或弹出Dialog中,必须使用Activity类型的Context;
(2)ContextImpl是上下文功能的实现类,上述三种类型的Context的具体功能都是这个在实现类实现的;
9.理解Activity,Window,View三者关系:
Actiivty会初始化一个Window(PhoneWindow),这个PhoneWindow有一个ViewRoot,他就是一个VIew或这说是VIewGroup,
ViewRoot通过addView方法一个个的添加View,这些VIew的监听事件都是由WindowManageService来接收消息,并回调Activity函数;
比喻:Activity是工匠,View是窗花,Window就是窗子,LayoutInflater是见到,xml文件是窗花的图纸;
10.四种LaunchMode及其使用场景:
(1)Standard(标准)模式:
启动方式:每次激活Activity时都会创建一个Activity实例,并放入任务栈中;
使用场景:大多数的Activity
(2)singleTop(栈顶复用)模式:
启动方式:如果在任务的栈顶正好有该Activity的实例,就重用该实例(会调用实例的onNewIntent()),否则就会重新创建一个新的实例;
使用场景:新闻类或者阅读类App的内容页面;
(3)singleTask(栈内复用)模式:
启动方式:只要栈内存在该Activity实例,就复用该实例(会调用实例的onNewIntent()),重用时,会让该实例回到栈顶,因此,在它上面的实例都会被移出栈;
使用场景:浏览器的主界面,不管从多少个应用启动浏览器,只会启动主页面一次,其余情况都走onNetIntent(),并且会清空主界面上的其他页面;
(4)singleInstance(单实例)模式:
启动方式:在一个新栈中创建该Activity的实例,并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity实例已经存在于摸一个栈中,任何应用再激活该Activity时,都会重用该栈中的实例(会调用实例的onNewIntent())。其效果相当于多个应用共享一个应用,不管谁激活该Activity都会进入同一个应用中。
使用场景:闹铃提醒,将闹铃与设置相分离;
11.View的绘制流程:(自定义控件的过程)
关于自定义控件:
(1)组合式控件:不需要我们自己绘制,而是使用原生控件组合承德新空间,如标题栏;
(2)继承原有控件:在原生控件提供的方法之外,添加一些自己需要的方法。如制作圆角,圆形图片;
(3)完全自定义控件:通过onMeasure(),onLayout(),onDraw等方法进行自定义绘制;如制作水波纹进度条;
关于View的绘制流程:
(1)onMeasure():测量视图的大小,从顶层父VIew到子View递归调用measure方法,measure方法又回调onMeasure()
(2)onLayout():确定View的位置,从顶层父View向子View的递归调用view.layout方法的过程,即父View根据上一步measure子View所得到的布局大小和布局参数,将子View放在合适的位置上;
(3)onDraw():绘制试图,ViewRoot创建一个Canvas对象,然后调用onDraw()。六个步骤:
<1>绘制视图的背景
<2>保存画布的图层(Layer)
<3>绘制VIew的内容
<4>绘制VIew的子视图(如果没有就不用)
<5>还原图层
<6>绘制滚动条
12.android事件分发机制:
从Activity开始传递,onDispatchTuochEvent()方法返回super向下传递,返回true或false都终止传递->事件传递到viewGroup中,onDispatchTouchEvent()返回super()会传递给其onInterceptTouchEvent(),返回true不在分发,返回false会向上传递,Activity的onTouchEvent会消费事件;->ViewGroup的onInterceptTouchEvent()返回super()或false就传递给子view的onDispatchTouchEvent(),返回true,自己消费,调用自己的onTouchEvent(),如果自己的onTouchEvent()返回super(),那么就继续向上传递;->子view的onDispatchTouchEvent会返回super()就传递给自身的onTouch(),返回true不在分发事件,返回false,向上传递;->子view的ontouch()返回true,不在分发事件,返回false传递给自身的onTouchEvent方法->子view的ontouchEvent()返回super()或false传递完成,子view消费事件;返回false,向上传;
当Activity接收到Touch事件,将遍历子view进行事件分发,当一个view需要此事件,那么就在其自身的onTouchEvent方法中返回true;
13.保存Actiivty状态:
onSaveInstanceState(Bundle)方法会在activity转入后台状态之前被调用,也就是onStop()方法之前,onPause()方法之后被调用的
14.Android几种动画:
(1)帧动画:通过制定每一帧的图片和播放事件,有序的进行播放而形成的动画效果;
(2)补间动画:通过指定view的初始状态,变化时间,变化方式,通过一系列的算法进行图形转换,从而形成动画效果,主要右Alpha,scale,Translate,rotate四种效果,特点是不能改变view的属性;
(3)属性动画:通过不断的改变view的属性,不断的重绘而形成动画效果;
15.Android跨进程通信的几种方式:
(1)service
(2)广播
(3)binder
(4)contentprovider
(5)intent
16.binder机制:
每一个进程都有一个dalvik vm实例,都有一块属于自己的内存空间,都在自己的内存上存储这自己的数据,执行着自己的操作,而binder就是两个进程之间通信的桥梁,binder是由client,service,servicemanager,和binder驱动程序组成的,其中,client,service,servicemanager是运行在用户空间的,而binder驱动程序是运行在内核空间的;
android面试(6)-Binder机制
17.Handler原理:
Handler中存在四个重要的对象,handler,message,messageQueue和looper轮循器,首先,handler将message发送给messageQueue,looper轮循器会不断地从messageQueue中取出message交给handler处理;
18.热修复原理:
虚拟机加载类时,都需要通过ClassLoader类加载器进行加载,classLoader有一个子类BaseDexClassLoader,而BaseDexClassLoader下有一个数组------DexPathList,用来存放dex文件的,当BaseDexClassLoader通过调用findClass()方法,实际上就是遍历数组,找到相应的dex文件,找到的话就直接将它return。而热修复就是将新的dex添加到该数组中,并且是在旧的dex之前。所以就会优先被取出来并且返回;
19.android内存泄漏即管理:
(1)handler,Asynctask等引起的内存泄漏;
解决方法:将handler声明为静态内部类,并持有外部leukemia的弱引用,并在onDestroy方法中调用removeAllMessage方法;
(2)单例模式下的内存泄漏:
传入applicationContext,由于ApplicationContext的生命周期和App一致,所以不会导致内存泄漏;
(3)非静态内部类创建静态实例引起的内存泄漏:
解决方法:将内部类修改为静态的
(4)资源对象没有关闭引起
(5)集合对象没有及时清理
(6)注册/反注册未成对使用
20.fragment与fragment,activity通信的方式:
(1)直接在fragment中调用另外一个fragment中的方法;
(2)使用接口回调
(3)使用广播
(4)fragment直接调用Activity的public方法
21.app优化问题“
(1)冷启动优化:app没有启动过或app进程被killed,系统中不存在该app进程,application的onCreate,首屏Activity的渲染都不要进行耗时操作,如果需要,那么放在子线程或者IntentService中
(2)布局优化:尽量不要使用过于复杂的嵌套,可以使用merge,viewStub,include等,如果布局必须很复杂,可以考虑自定义控件
(3)响应优化:Android系统每隔16ms会发出VSYNC
UI卡顿的原因:
<1>过于复杂的布局
<2>主线程做了复杂运算
<3>频繁的GC,导致频繁GC大致有两个原因:一个是大量的对象被创建出,并很快又被销毁,这就是内存抖动的原因,例如在序列化时,使用Serializable 进行序列化,还有一个原因就是瞬间产生大量的对象严重占用内存区域
(4)电池优化:
<1>优化网络请求
<2>定位中使用GPS,记得关闭
(5)网络优化:
<1>使用GZip压缩request和response,减少传输数据量,从而减少流量消耗
<2>适当做网络缓存
<3>可以和服务端沟通,优化API
(5)图片优化
<1>对图片本身进行操作,尽量不要使用setImageBitmap,setImageResource,BitmapFactory.decodeResource来设置一张大图,因为这些方法都是在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存;
<2>图片进行缩放的比例,sdk建议值为2;
<3>不用的图片需要调用recycle()方法回收内存
22.Java GC
GC算法的核心思想是:对虚拟机可用内存空间,即堆空间中的对象进行识别,如果对象正在被引用,那么就是存活对象;反之,如果对象不在被引用,则为垃圾对象,可以回收其占据的空间,用于在分配。垃圾收集算法的选择和垃圾收集系统的合理调节直接影响着系统性能;
23.ANR
产生原因:
(1)5s内无法响应用户输入事件(例如键盘的输入,触摸屏幕等)
(2)BroadcastReceiver在10s内无法结束
(3)Service在20s内无法结束
解决方法:
(1)不要在主线程中做耗时操作,而应放在子线程中实现。如onCreate()和onResume里尽可能少的去创建操作
(2)应用程序应该避免在BroadcastReceiver里进行耗时操作
(3)避免在Intent receiver中启动一个Activity,因为他会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点
(4)service是运行在主线程的,所以在service中做耗时操作,必须放在子线程中