安卓面试

一、自定义view的流程

记清楚函数调用的顺序才能准确地进行调用。

根据调用链,可将整个绘制过程分为三部分: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。

//第一种启动式

  1. btn1.setOnClickListener(new View.OnClickListener() {  
  2.             @Override  
  3.             public void onClick(View v) {  
  4.                 Intent it=new Intent(Main.this,MyService.class);  
  5.                 startService(it);  
  6.                 //bindService(it,conn,Service.BIND_AUTO_CREATE);  
  7.             }  
  8.         }); 
//第二种绑定式

  1. private MyService service;  
  2.     public ServiceConnection conn=new ServiceConnection(){  
  3.   
  4.         @Override  
  5.         public void onServiceConnected(ComponentName name, IBinder service) {  
  6.             Log.v("tag","onServiceConnected"+",ComponentName:"+name);  
  7.             Main.this.service=((MyService.IBinderImpl)service).getInstance();  
  8.         }  
  9.   
  10.         @Override  
  11.         public void onServiceDisconnected(ComponentName name) {  
  12.             Log.v("tag","onServiceDisconnected");  
  13.             Main.this.service=null;  
  14.         }  
  15.           
  16.     };  
  17. //这是servise的代码
    1. public class MyService extends Service {  
    2.   
    3.     @Override  
    4.     public void onCreate(){  
    5.         super.onCreate();  
    6.         Log.v("tag","服务:onCreate");  
    7.           
    8.     }  
    9.     @Override  
    10.     public void onDestroy(){  
    11.         super.onCreate();  
    12.         Log.v("tag","服务:onDestroy");  
    13.     }  
    14.     @Override  
    15.     public int onStartCommand(Intent intent,int flags,int startId){  
    16.         Log.v("tag","服务:onStartCommand");  
    17.         return super.onStartCommand(intent, flags, startId);  
    18.     }  
    19.       
    20.     @Override  
    21.     public void onRebind(Intent it){  
    22.         super.onRebind(it);  
    23.         Log.v("tag","服务:onRebind");  
    24.     }  
    25.       
    26.     @Override  
    27.     public boolean onUnbind(Intent it){  
    28.         Log.v("tag","服务:onUnbind");  
    29.         return super.onUnbind(it);  
    30.           
    31.     }  
    32.       
    33.     public class IBinderImpl extends Binder{  
    34.         public MyService getInstance(){  
    35.             return MyService.this;  
    36.         }  
    37.     };  
    38.     @Override  
    39.     public IBinder onBind(Intent intent) {  
    40.         Log.v("tag","服务:onBind");  
    41.         return new IBinderImpl();  
    42.     }  
    43.   
    44. }  
九.安卓如何处理异步
    1.handler 2.Thread
十、app的优化,内存,绘制,OOM.
- 响应时间(Response Time) 
- 界面卡顿(ANR) 
- 耗内存(Memory) 
- 内存泄露(Out of memory)

界面卡顿

ANR表示”应用程序无响应”,这个是需要我们避免发生的事情,出现这个异常的原因: 
- 主线程 (“事件处理线程” / “UI线程”) 在5秒内没有响应输入事件 
- BroadcastReceiver在10秒内没有执行完毕

导致ANR的原因有很多,一般情况就是在UI线程做了耗时的操作,例如”网络请求”、数据库操作。

那么如何避免? 
- UI线程只做界面刷新,不做任何耗时操作,耗时操作放在子线程来做 
- 可以使用Thread+handle或者AsyncTask来进行逻辑处理





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值