继上一篇空发议论,这一篇开始把我面试时候的总结分享出来。
一、ANR的情况和避免
由Activity Manager和WindowManager监视,下列情况:
1、主线程5s内没有影响输入事件
2、BroadCastReceiver在10s内没有执行完毕
3、Service主线程耗时操作超过15s
解决方案案:网络通信、数据库和高耗时的计算放在子线程中,用handler.sendMessage、runOnUIThread和AsyncTask更新UI。
二、View绘制
2.1、绘制流程
1、onMeasure测量视图大小,MeasureSpec.makeMeasureSpec三种方式:AT_MOST最大不能超过,EXACTLY精确,UNSPECIFIED不限定size|mode
2、onLayout确定view的位置,实际应用:浏览器小红点的位置
3、onDraw绘制View。
2.2、draw的绘制步骤
1、画background
2、canvas.save
3、View自身
4、子View
5、canvas.restore
6、绘制装饰如滚动条
2.3、canvas.save和canvas.restore
a、canvas.save、restore确保对坐标系的改动只发生在save、restore之间的代码
也就是save可以调用canvas的旋转rotate、缩放,平移,剪裁和错切,restore恢复canvas上述的改动,避免对后续绘制进行的影响
例如:canvas.rotate(45)画一个矩形,这个不用save、restore罩住。那么如果以后再画的矩形也是45旋转的
b、save和restore配对使用,restore只能比save少,不能多。多了引发error
c、save将当前canvas状态入栈,restore把最后一个状态弹出栈
三、自定义View如何考虑机型适配
ldpi、mdpi、hdpi、xhdpi、xxhdpi和xxxhdpi的dpi
dp和px的关系:px =dp*(dpi/160)
2、a、多使用wrap_content、match_parent和dp
b、不要用具体的像素值
c、不用AbsoluteLayout,使用RelativeLayout
d、不同分辨率不同大小的图片
e、manifest中声明支持
四、View、SurfaceView、GLSurfaceView的区别
4.1、View必须在UI主线程更新,速度慢
a、如果更新耗时,UI主线程阻塞,造成ANR
b、SurfaceView存在事件同步问题
4.2、SurfaceView是View的子类,采用双缓存机制,在新的工作线程刷新界面,速度比View快
a、SurfaceView是View子类
b、SurfaceView自身有GLSurfaceView和VideoSurfaceView
c、GL、视频播放、Camera摄像头都采用SurfaceView
4.3、GLSurfaceView是SurfaceView的子类,openGL专用
五、Android图片占用内存计算公式
5.1、常用的ARGB_8888存储时:
占用内存 = 图片长 * 图片宽 * 4字节
图片长 = 图片原始长 * (设备dpi/图片所在资源文件夹dpi)
图片宽 =图片原始长 * (设备dpi/图片所在资源文件夹dpi)
例如:红米dpi为320,图片200*230放在hdpi文件夹中,hdpi文件夹对应dpi为240,那么图片长 = 200 * 320/240)= 266.67。同理,xxhdpi文件夹对应480,代入公式图片长为133.33
5.2、RGB_565存储时,2字节;ALPHA_8为1字节,ARGB_4444为2字节
六、View和ViewGroup事件分发的函数
6.1、View事件的窗口传递
1、事件传递为Activity->PhoneWindow->DecorView->ViewGroup->View
2、不拦截就用requestDisallowInterceptTouchEvent
6.2、View有事件顺序
1、dispatchTouchEvent->setOnTouchListener的onTouch->OnTouchEvent->onClick
2、setOnTouchListener优先级高于OnTouchEvent
6.3、ViewGroup有dispatchTouchEvent->onInterceptTouchEvent->onTouchEvent
6.4、所有事件都不接收就消耗在Activity的onTouchEvent
public boolean dispatchTouchEvent(MotionEvent ev) {
if(getWindow().superDispatchTouchEvent(ev)) {
return true;
}
returnonTouchEvent(ev);
}
6.5、onInterceptTouchEvent返回true,交给OnTouchEvent,OnTouchEvent又返回false,则该事件传递上一层view的onTouchEvent处理,都是false则传递到Activity的onTouc;如果返回true,那么整个Touch过程事件都交由整个onTouchEvent处理。
6.6、View的dispatchTouchEvent调用顺序
1、在dispatchTouchEvent中优先用setOnTouchLister的onTouch
2、再onTouchEvent
3、最后是onTouchEvent的ACTION_UP中performClick条件执行onClick。
6.7、ViewGroup的dispatchTouchEvent中伪代码
publicboolean dispatchTouchEvent(MotionEvent ev) {
boolean result =false;
if(!onInterceptTouchEvent(ev)) {
result =child.dispatchTouchEvent(ev);//如果没有拦截就交给子View
}
//拦截了或者子View都没被消费
if(!result) {
result = onTouchEvent(ev);
}
return result;
}