安卓面试
2017-12-01 00:12
176 查看
一、自定义view的流程
记清楚函数调用的顺序才能准确地进行调用。
根据调用链,可将整个绘制过程分为三部分:Measure - Layout - Draw
一、定义自定义View的类。
为了创建点击可切换的形状的自定义View,我们继承View,编写构造方法。实现三个构造方法,最终调用三个参数的构造方法。
六、Servise的生命周期,有几种Servise
开启一个服务有两种方法,第一种为startSevice,第二种则是bindService。
//第一种启动式
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent it=new Intent(Main.this,MyService.class);
startService(it);
//bindService(it,conn,Service.BIND_AUTO_CREATE);
}
});
//第二种绑定式
private MyService service;
public ServiceConnection conn=new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.v("tag","onServiceConnected"+",ComponentName:"+name);
Main.this.service=((MyService.IBinderImpl)service).getInstance();
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.v("tag","onServiceDisconnected");
Main.this.service=null;
}
};
//这是servise的代码
public class MyService extends Service {
@Override
public void onCreate(){
super.onCreate();
Log.v("tag","服务:onCreate");
}
@Override
public void onDestroy(){
super.onCreate();
Log.v("tag","服务:onDestroy");
}
@Override
public int onStartCommand(Intent intent,int flags,int startId){
Log.v("tag","服务:onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onRebind(Intent it){
super.onRebind(it);
Log.v("tag","服务:onRebind");
}
@Override
public boolean onUnbind(Intent it){
Log.v("tag","服务:onUnbind");
return super.onUnbind(it);
}
public class IBinderImpl extends Binder{
public MyService getInstance(){
return MyService.this;
}
};
@Override
public IBinder onBind(Intent intent) {
Log.v("tag","服务:onBind");
return new IBinderImpl();
}
}
九.安卓如何处理异步
1.handler 2.Thread
十、app的优化,内存,绘制,OOM.
- 响应时间(Response Time)
- 界面卡顿(ANR)
- 耗内存(Memory)
- 内存泄露(Out of memory)
ANR表示”应用程序无响应”,这个是需要我们避免发生的事情,出现这个异常的原因:
- 主线程 (“事件处理线程” / “UI线程”) 在5秒内没有响应输入事件
- BroadcastReceiver在10秒内没有执行完毕
导致ANR的原因有很多,一般情况就是在UI线程做了耗时的操作,例如”网络请求”、数据库操作。
那么如何避免?
- UI线程只做界面刷新,不做任何耗时操作,耗时操作放在子线程来做
- 可以使用Thread+handle或者AsyncTask来进行逻辑处理
记清楚函数调用的顺序才能准确地进行调用。
根据调用链,可将整个绘制过程分为三部分:Measure - Layout - Draw
一、定义自定义View的类。
为了创建点击可切换的形状的自定义View,我们继承View,编写构造方法。实现三个构造方法,最终调用三个参数的构造方法。
public class CustomView extends View { public CustomView(Context context) { this(context, null); } public CustomView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CustomView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } }
二、把自定义View加入到Layout中
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <cn.edu.zafu.view.CustomView android:id="@+id/customview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" /> </RelativeLayout>
第一步:当activity启动的时候,触发初始化view过程的是由Window对象的DecorView调用View(具体怎样从xml中读取是用LayoutInflater.from(context).inflate)对象的 public final void measure(int widthMeasureSpec, int heightMeasureSpec)方法开始的,这个方法是final类型的,也就是所有的子类都不能继承该方法,保证android初始化view的原理不变。具体参数类值,后面会介绍。 第二步:View的measure方法 onMeasure(widthMeasureSpec, heightMeasureSpec),该方法进行实质性的view大小计算。注意:view的大小是有父view和自己的大小决定的,而不是单一决定的。这也就是为什么ViewGroup的子类会重新该方法,比如LinearLayout等。因为他们要计算自己和子view的大小。View基类有自己的实现,只是设置大小。其实根据源码来看,measure的过程本质上就是把Match_parent和wrap_content转换为实际大小 第三步:当measure结束时,回到DecorView,计算大小计算好了,那么就开始布局了,开始调用view的 public final void layout(int l, int t, int r, int b),该还是也是final类型的,目的和measure方法一样。layout方法内部会调用onlayout(int l, int t, int r, int b )方法,二ViewGroup将此方法abstract的了,所以我们继承ViewGroup的时候,需要重新该方法。该方法的本质是通过measure计算好的大小,计算出view在屏幕上的坐标点 第四步:measure过了,layout过了,那么就要开始绘制到屏幕上了,所以开始调用view的 public void draw(Canvas canvas)方法,此时方法不是final了,原因是程序员可以自己画,内部会调用ondraw,我们经常需要重写的方法。
六、Servise的生命周期,有几种Servise
开启一个服务有两种方法,第一种为startSevice,第二种则是bindService。
//第一种启动式
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent it=new Intent(Main.this,MyService.class);
startService(it);
//bindService(it,conn,Service.BIND_AUTO_CREATE);
}
});
//第二种绑定式
private MyService service;
public ServiceConnection conn=new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.v("tag","onServiceConnected"+",ComponentName:"+name);
Main.this.service=((MyService.IBinderImpl)service).getInstance();
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.v("tag","onServiceDisconnected");
Main.this.service=null;
}
};
//这是servise的代码
public class MyService extends Service {
@Override
public void onCreate(){
super.onCreate();
Log.v("tag","服务:onCreate");
}
@Override
public void onDestroy(){
super.onCreate();
Log.v("tag","服务:onDestroy");
}
@Override
public int onStartCommand(Intent intent,int flags,int startId){
Log.v("tag","服务:onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onRebind(Intent it){
super.onRebind(it);
Log.v("tag","服务:onRebind");
}
@Override
public boolean onUnbind(Intent it){
Log.v("tag","服务:onUnbind");
return super.onUnbind(it);
}
public class IBinderImpl extends Binder{
public MyService getInstance(){
return MyService.this;
}
};
@Override
public IBinder onBind(Intent intent) {
Log.v("tag","服务:onBind");
return new IBinderImpl();
}
}
九.安卓如何处理异步
1.handler 2.Thread
十、app的优化,内存,绘制,OOM.
- 响应时间(Response Time)
- 界面卡顿(ANR)
- 耗内存(Memory)
- 内存泄露(Out of memory)
界面卡顿
ANR表示”应用程序无响应”,这个是需要我们避免发生的事情,出现这个异常的原因: - 主线程 (“事件处理线程” / “UI线程”) 在5秒内没有响应输入事件
- BroadcastReceiver在10秒内没有执行完毕
导致ANR的原因有很多,一般情况就是在UI线程做了耗时的操作,例如”网络请求”、数据库操作。
那么如何避免?
- UI线程只做界面刷新,不做任何耗时操作,耗时操作放在子线程来做
- 可以使用Thread+handle或者AsyncTask来进行逻辑处理
相关文章推荐
- (面试必备)安卓面试题
- 【安卓面试笔记】Service(四)
- 安卓面试方面的一些知识(仅供参考)
- 安卓面试之IntentService和Service的区别在哪?HandlerThread的使用
- 安卓面试技术点之xmpp知识准备
- android面试java算法题【安卓进化四】
- 安卓面试备战复习点
- 百度安卓面试总结
- 魅族 安卓开发面试 问题整理(2017.12.13)
- 安卓面试必问一View的事件分发
- 安卓面试技术点之xmpp知识准备Socket服务器的终结
- 武汉某某等公司移动开发岗位(安卓开发)面试心得
- 安卓面试备考题收集
- 华为面试经历-安卓应用开发工程师
- 安卓面试提aa
- 安卓面试知识点
- 面试安卓游戏开发岗位
- 安卓面试易考题(二)
- 阿里安卓面试分析: Android应用的闪退(crash)问题跟踪和解析
- 安卓面试(1)