面试干货 for Android(一)

最近在准备实习,一直在搜寻一些Android方面基础的知识,现在做一个小小的总结。


一. 安卓view绘制机制和加载过程
         
  • 1.ViewRootImpl会调用performTraversals(),其内部会调用performMeasure()、performLayout、performDraw()。

  • 2.performMeasure()会调用最外层的ViewGroup的measure()-->onMeasure(),ViewGroup的onMeasure()是抽象方法,但其提供了measureChildren(),这之中会遍历子View然后循环调用measureChild()这之中会用getChildMeasureSpec()+父View的MeasureSpec+子View的LayoutParam一起获取本View的MeasureSpec,然后调用子View的measure()到View的onMeasure()-->setMeasureDimension(getDefaultSize(),getDefaultSize()),getDefaultSize()默认返回measureSpec的测量数值,所以继承View进行自定义的wrap_content需要重写。

  • 3.performLayout()会调用最外层的ViewGroup的layout(l,t,r,b),本View在其中使用setFrame()设置本View的四个顶点位置。在onLayout(抽象方法)中确定子View的位置,如LinearLayout会遍历子View,循环调用setChildFrame()-->子View.layout()。

  • 4.performDraw()会调用最外层ViewGroup的draw():其中会先后调用background.draw()(绘制背景)、onDraw()(绘制自己)、dispatchDraw()(绘制子View)、onDrawScrollBars()(绘制装饰)。

  • 5.MeasureSpec由2位SpecMode(UNSPECIFIED、EXACTLY(对应精确值和match_parent)、AT_MOST(对应warp_content))和30位SpecSize组成一个int,DecorView的MeasureSpec由窗口大小和其LayoutParams决定,其他View由父View的MeasureSpec和本View的LayoutParams决定。ViewGroup中有getChildMeasureSpec()来获取子View的MeasureSpec。

  • 6.三种方式获取measure()后的宽高:

    • 1.Activity#onWindowFocusChange()中调用获取

    • 2.view.post(Runnable)将获取的代码投递到消息队列的尾部。

    • 3.ViewTreeObservable.

二.、activty的加载过程

     
  • 1.Activity中最终到startActivityForResult()(mMainThread.getApplicationThread()传入了一个ApplicationThread检查APT)
    ->Instrumentation#execStartActivity()和checkStartActivityResult()(这是在启动了Activity之后判断Activity是否启动成功,例如没有在AM中注册那么就会报错)
    ->ActivityManagerNative.getDefault().startActivity()(类似AIDL,实现了IAM,实际是由远端的AMS实现startActivity())
    ->ActivityStackSupervisor#startActivityMayWait()
    ->ActivityStack#resumeTopActivityInnerLocked
    ->ActivityStackSupervisor#realStartActivityLocked()(在这里调用APT的scheduleLaunchActivity,也是AIDL,不过是在远端调起了本进程Application线程)
    ->ApplicationThread#scheduleLaunchActivity()(这是本进程的一个线程,用于作为Service端来接受AMS client端的调起)
    ->ActivityThread#handleLaunchActivity()(接收内部类H的消息,ApplicationThread线程发送LAUNCH_ACTIVITY消息给H)
    ->最终在ActivityThread#performLaunchActivity()中实现Activity的启动完成了以下几件事:

  • 2.从传入的ActivityClientRecord中获取待启动的Activity的组件信息

  • 3.创建类加载器,使用Instrumentation#newActivity()加载Activity对象

  • 4.调用LoadedApk.makeApplication方法尝试创建Application,由于单例所以不会重复创建。

  • 5.创建Context的实现类ContextImpl对象,并通过Activity#attach()完成数据初始化和Context建立联系,因为Activity是Context的桥接类,
    最后就是创建和关联window,让Window接收的事件传给Activity,在Window的创建过程中会调用ViewRootImpl的performTraversals()初始化View。

  • 6.Instrumentation#callActivityOnCreate()->Activity#performCreate()->Activity#onCreate().onCreate()中会通过Activity#setContentView()调用PhoneWindow的setContentView()
    更新界面。

三、Activity的启动模式

      
  • 1.standard:默认标准模式,每启动一个都会创建一个实例,

  • 2.singleTop:栈顶复用,如果在栈顶就调用onNewIntent复用,从onResume()开始

  • 3.singleTask:栈内复用,本栈内只要用该类型Activity就会调到栈顶复用,从onResume()开始

  • 4.singleInstance:单例模式,除了3中特性,系统会单独给该Activity创建一个栈


四、Activity缓存方法

      
  • 1.配置改变导致Activity被杀死,横屏变竖屏:在onStop之前会调用onSaveInstanceState()保存数据在重建Activity之后,会在onStart()之后调用onRestoreInstanceState(),并把保存下来的Bundle传给onCreate()和它会默认重建Activity当前的视图,我们可以在onCreate()中,回复自己的数据。

  • 2.内存不足杀掉Activity,优先级分别是:前台可见,可见非前台,后台


五、Service的生命周期(两种启动方法,有什么不同)

     
  • 1.context.startService() ->onCreate()- >onStart()->Service running-->(如果调用context.stopService() )->onDestroy() ->Service shut down

    • 1.如果Service还没有运行,则调用onCreate()然后调用onStart();

    • 2.如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次。

    • 3.调用stopService的时候直接onDestroy,

    • 4.如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。该Service的调用者再启动起来后可以通过stopService关闭Service。

  • 2.context.bindService()->onCreate()->onBind()->Service running-->onUnbind() -> onDestroy() ->Service stop

    • 1.onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。

    • 2.这个时候会把调用者和Service绑定在一起,Context退出了,Service就会调用onUnbind->onDestroy相应退出。

    • 3.所以调用bindService的生命周期为:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值