一、性能优化1.如何对 android 应用进行性能分析android 性能主要之响应速度 和ui刷新速度。
可以参考博客:android系统性能调优工具介绍
首先从函数的耗时来说,有一个工具traceview 这是androidsdk自带的工作,用于测量函数耗时的。
ui布局的分析,可以有2块,一块就是hierarchy viewer 可以看到view的布局层次,以及每个view刷新加载的时间。
这样可以很快定位到那块layout & view 耗时最长。
还有就是通过自定义view来减少view的层次。
2.什么情况下会导致内存泄露内存泄露是个折腾的问题。
什么时候会发生内存泄露?内存泄露的根本原因:长生命周期的对象持有短生命周期的对象。短周期对象就无法及时释放。
i. 静态集合类引起内存泄露
主要是hashmap,vector等,如果是静态集合 这些集合没有及时setnull的话,就会一直持有这些对象。
ii.remove 方法无法删除set集 objects.hash(firstname, lastname);
经过测试,hashcode修改后,就没有办法remove了。
iii. observer 我们在使用监听器的时候,往往是addxxxlistener,但是当我们不需要的时候,忘记removexxxlistener,就容易内存leak。
广播没有unregisterrecevier
iv.各种数据链接没有关闭,数据库contentprovider,io,sokect等。cursor
v.内部类:
java中的内部类(匿名内部类),会持有宿主类的强引用this。
所以如果是new thread这种,后台线程的操作,当线程没有执行结束时,activity不会被回收。
context的引用,当textview 等等都会持有上下文的引用。如果有static drawable,就会导致该内存无法释放。
vi.单例
单例 是一个全局的静态对象,当持有某个复制的类a是,a无法被释放,内存leak。
3.如何避免 oom 异常首先oom是什么?当程序需要申请一段“大”内存,但是虚拟机没有办法及时的给到,即使做了gc操作以后
这就会抛出 outofmemoryexception 也就是oom
android的oom怎么样?为了减少单个app对整个系统的影响,android为每个app设置了一个内存上限。
public void getmemorylimited(activity context) { activitymanager activitymanager =(activitymanager)context.getsystemservice(context.activity_service); system.out.println(activitymanager.getmemoryclass()); system.out.println(activitymanager.getlargememoryclass()); system.out.println(runtime.getruntime().maxmemory()/(1024*1024)); }
09-10 10:20:00.477 4153-4153/com.joyfulmath.samples i/system.out: 19209-10 10:20:00.477 4153-4153/com.joyfulmath.samples i/system.out: 51209-10 10:20:00.477 4153-4153/com.joyfulmath.samples i/system.out: 192
htc m7实测,192m上限。512m 一般情况下,192m就是上限,但是由于某些特殊情况,android允许使用一个更大的ram。
如何避免oom减少内存对象的占用i.arraymap/sparsearray代替hashmap
ii.避免在android里面使用enum
iii.减少bitmap的内存占用
insamplesize:缩放比例,在把图片载入内存之前,我们需要先计算出一个合适的缩放比例,避免不必要的大图载入。decode format:解码格式,选择argb_8888/rbg_565/argb_4444/alpha_8,存在很大差异。iv.减少资源图片的大小,过大的图片可以考虑分段加载
内存对象的重复利用大多数对象的复用,都是利用对象池的技术。
i.listview/gridview/recycleview contentview的复用
ii.inbitmap 属性对于内存对象的复用argb_8888/rbg_565/argb_4444/alpha_8
这个方法在某些条件下非常有用,比如要加载上千张图片的时候。
iii.避免在ondraw方法里面 new对象
iv.stringbuilder 代替+
4.android 中如何捕获未捕获的异常public class crashhandler implements thread.uncaughtexceptionhandler { private static crashhandler instance = null; public static synchronized crashhandler getinstance() { if(instance == null) { instance = new crashhandler(); } return instance; } public void init(context context) { thread.setdefaultuncaughtexceptionhandler(this); } @override public void uncaughtexception(thread thread, throwable ex) { stringbuilder stringbuilder = new stringbuilder(); stringbuilder.append("thread:"); stringbuilder.append(thread.tostring()); stringbuilder.append("\t"); stringbuilder.append(ex); tracelog.i(stringbuilder.tostring()); tracelog.printcallstatck(ex); }}
crashhandler
关键是实现thread.uncaughtexceptionhandler
然后是在application的oncreate里面注册。
5.anr 是什么?怎样避免和解决 anr(重要)anr->application not responding
也就是在规定的时间内,没有响应。
三种类型:
1). keydispatchtimeout(5 seconds) --主要类型按键或触摸事件在特定时间内无响应
2). broadcasttimeout(10 seconds) --broadcastreceiver在特定时间内无法处理完成
3). servicetimeout(20 seconds) --小概率类型 service在特定的时间内无法处理完成
为什么会超时:事件没有机会处理 & 事件处理超时
怎么避免anranr的关键
是处理超时,所以应该避免在ui线程,broadcastreceiver 还有service主线程中,处理复杂的逻辑和计算
而交给work thread操作。
1)避免在activity里面做耗时操作,oncreate & onresume
2)避免在onreceiver里面做过多操作
3)避免在intent receiver里启动一个activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。
4)尽量使用handler来处理ui thread & workthread的交互。
如何解决anr首先定位anr发生的log:
04-01 13:12:11.572 i/inputdispatcher( 220): application is not responding:window{2b263310com.android.email/com.android.email.activity.splitscreenactivitypaused=false}. 5009.8ms since event, 5009.5ms since waitstarted
cpuusage from 4361ms to 699ms ago ----cpu在anr发生前的使用情况04-0113:12:15.872 e/activitymanager( 220): 100%total: 4.8% user + 7.6% kernel + 87% iowait04-0113:12:15.872 e/activitymanager( 220): cpuusage from 3697ms to 4223ms later:-- anr后cpu的使用量
从log可以看出,cpu在做大量的io操作。
所以可以查看io操作的地方。
当然,也有可能cpu占用不高,那就是 主线程被block住了。
6.android 线程间通信有哪几种方式1)共享变量(内存)
2)管道
3)handle机制
runonuithread(runnable)
view.post(runnable)
7.devik 进程,linux 进程,线程的区别dalvik进程。
每一个android app都会独立占用一个dvm虚拟机,运行在linux系统中。
所以dalvik进程和linux进程是可以理解为一个概念。
8.描述一下 android 的系统架构从小到上就是:
linux kernel,lib dalvik vm ,application framework, app
9.android 应用对内存是如何限制的?我们应该如何合理使用内存?activitymanager.getmemoryclass() 获取内存限制。
关于合理使用内存,其实就是避免oom & 内存泄露中已经说明。
10. 简述 android 应用程序结构是哪些1)main code
2) unit test
3)mianifest
4)res->drawable,drawable-xxhdpi,layout,value,mipmap
mipmap 是一种很早就有的技术了,翻译过来就是纹理映射技术.
google建议只把启动图片放入。
5)lib
6)color
11.请解释下 android 程序运行时权限与文件系统权限的区别文件的系统权限是由linux系统规定的,只读,读写等。
运行时权限,是对于某个系统上的app的访问权限,允许,拒绝,询问。该功能可以防止非法的程序访问敏感的信息。
12.framework 工作方式及原理,activity 是如何生成一个 view 的,机制是什么framework是android 系统对 linux kernel,lib库等封装,提供wms,ams,bind机制,handler-message机制等方式,供app使用。
简单来说framework就是提供app生存的环境。
1)activity在attch方法的时候,会创建一个phonewindow(window的子类)
2)oncreate中的setcontentview方法,会创建decorview
3)decorview 的addview方法,会把layout中的布局加载进来。
13.多线程间通信和多进程之间通信有什么不同,分别怎么实现线程间的通信可以参考第6点。
进程间的通信:bind机制(ipc->aidl),linux级共享内存,boradcast,
activity 之间,activity & serview之间的通信,无论他们是否在一个进程内。
14.android 屏幕适配屏幕适配的方式:xxxdpi, wrap_content,match_parent. 获取屏幕大小,做处理。
dp来适配屏幕,sp来确定字体大小
drawable-xxdpi, values-1280*1920等 这些就是资源的适配。
wrap_content,match_parent, 这些是view的自适应
weight,这是权重的适配。
15.什么是 aidl 以及如何使用android interface definition language
aidl是使用bind机制来工作。
参数:
java原生参数
string
parcelable
list & map 元素 需要支持aidl
16.handler 机制参考:android 进程/线程管理(一)----消息机制的框架 这个系类。
17.事件分发机制android 事件分发机制
18.子线程发消息到主线程进行更新 ui,除了 handler 和 asynctask,还有什么eventbus,广播,view.post, runinuithread
但是无论各种花样,本质上就2种:handler机制 + 广播
19.子线程中能不能 new handler?为什么必须可以。子线程 可以new 一个mainhandler,然后发送消息到ui thread。
20.android 中的动画有哪几类,它们的特点和区别是什么视图动画,或者说补间动画。只是视觉上的一个效果,实际view属性没有变化,性能好,但是支持方式少。
属性动画,通过变化属性来达到动画的效果,性能略差,支持点击等事件。android 3.0
帧动画,通过drawable一帧帧画出来。
gif动画,原理同上,canvas画出来。
具体可参考:https://i.cnblogs.com/posts?categoryid=672052
21.如何修改 activity 进入和退出动画 overridependingtransition
22.surfaceview & view 的区别view的更新必须在ui thread中进行
surfaceview会单独有一个线程做ui的更新。
surfaceview 支持open gl绘制。
二、项目框架的使用23.开发中都使用过哪些框架、平台i.eventbus 事件分发机制,由handler实现,线程间通信
ii.xutils->dbutils,viewutils,httputils,bitmaputils
iii.百度地图
iv.volley
v.fastjson
vi.picciso
vii.友盟
viii.zxing
ix.gson
24.使用过那些自定义viewpull2refreshlistview
25.自定义控件:绘制圆环的实现过程package com.joyfulmath.samples.cycle;import android.content.context;import android.graphics.canvas;import android.graphics.paint;import android.util.attributeset;import android.view.view;/** * created by administrator on 2016/9/11 0011. */public class cycleview extends view { paint mpaint = new paint(); public cycleview(context context) { this(context, null); } public cycleview(context context, attributeset attrs) { super(context, attrs); initview(); } private void initview() { mpaint.setantialias(true); mpaint.setstyle(paint.style.stroke); mpaint.setstrokewidth(20); } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); canvas.drawcircle(100,100,50,mpaint); }}
cycleview
关键是canvas.drawcycle & paint.setsytle(stoken)
26.自定义控件:摩天轮的实现过程27.gridlayout的使用可以不需要adapter
28.流式布局的实现过程tbd.
29.第三方登陆qq & 微信都有第三方登陆的sdk,要去注册app
30.第三方支付需要看支付宝的api文档
以上就是android高级面试题及答案分析的详细内容。
