美文网首页
Android面试笔记

Android面试笔记

作者: 小强子同学 | 来源:发表于2017-08-07 09:31 被阅读190次

    v:* {behavior:url(#default#VML);}
    o:* {behavior:url(#default#VML);}
    w:* {behavior:url(#default#VML);}
    .shape {behavior:url(#default#VML);}

    Normal

    0

    false

    false

    false

    false

    EN-US

    ZH-CN

    X-NONE

    /* Style Definitions */
    table.MsoNormalTable
    {mso-style-name:"Table Normal";
    mso-tstyle-rowband-size:0;
    mso-tstyle-colband-size:0;
    mso-style-noshow:yes;
    mso-style-priority:99;
    mso-style-parent:"";
    mso-padding-alt:0in 5.4pt 0in 5.4pt;
    mso-para-margin:0in;
    mso-para-margin-bottom:.0001pt;
    mso-pagination:widow-orphan;
    font-size:10.5pt;
    mso-bidi-font-size:11.0pt;
    font-family:"Calibri",sans-serif;
    mso-ascii-font-family:Calibri;
    mso-ascii-theme-font:minor-latin;
    mso-hansi-font-family:Calibri;
    mso-hansi-theme-font:minor-latin;
    mso-bidi-font-family:"Times New Roman";
    mso-bidi-theme-font:minor-bidi;
    mso-font-kerning:1.0pt;}

    Activity:

    ·
    生命周期:对话框遮挡,其他Activity遮挡,锁屏,屏幕旋转,内存不足被杀掉。

    ·
    onNewIntent调用时onCreate(),onStart()方法不会被调用

    ·
    可以把不同的 应用中的activity的taskAffinity设置成相同的值,这样的话这两个activity虽然不在同一应用中,却会在运行时分配到同一任务中

    Context:

    ·
    继承关系

    [图片上传中。。。(1)]

    ·
    初始化顺序:

    [图片上传中。。。(2)]

    ·
    IntentService:省去了在Service中手动开线程的麻烦,不用手动停止Service

    ·
    其他

    ContentProvider:

    ·
    管理android以结构化方式存放的数据,以相对安全的方式封装数据(表)并且提供简易的处理机制和统一的访问接口供其他程序调用。封装。对数据进行封装,提供统一的接口,使用者完全不必关心这些数据是在DB,XML、Preferences或者网络请求来的。当项目需求要改变数据来源时,使用我们的地方完全不需要修改。

    提供一种跨进程数据共享的方式。

    ·
    URI

    [图片上传中。。。(3)]

    ·
    ContentResolver通过URI来查询ContentProvider中提供的数据。除了URI以外,还必须知道需要获取的数据段的名称,以及此数据段的数据类型。如果你需要获取一个特定的记录,你就必须知道当前记录的ID,也就是URI中D部分。

    ·
    ContentObserver(内容观察者),目的是观察特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它

    ·
    其他

    BroadcastReceiver:

    ·
    在onResume()注册、onPause()注销是因为onPause()在App死亡前一定会被执行,从而保证广播在App死亡前一定会被注销,从而防止内存泄露。不在onCreate()
    & onDestory() 或 onStart() & onStop()注册、注销是因为:当系统因为内存不足(优先级更高的应用需要内存,请看上图红框)要回收Activity占用的资源时,Activity在执行完onPause()方法后就会被销毁,有些生命周期方法onStop(),onDestory()就不会执行。当再回到此Activity时,是从onCreate方法开始执行。

    ·

    [图片上传中。。。(4)]

    ·
    对于不同注册方式的广播接收器回调OnReceive(Context
    context,Intent
    intent)中的context返回值是不一样的:

    对于静态注册(全局+应用内广播),回调onReceive(context,
    intent)中的context返回值是:ReceiverRestrictedContext;

    对于全局广播的动态注册,回调onReceive(context,
    intent)中的context返回值是:Activity
    Context;

    对于应用内广播的动态注册(LocalBroadcastManager方式),回调onReceive(context,
    intent)中的context返回值是:Application
    Context。

    对于应用内广播的动态注册(非LocalBroadcastManager方式),回调onReceive(context,
    intent)中的context返回值是:Activity
    Context;

    Handler:

    ·
    主线程中已经实现了两个重要的Looper方法,
    ActivityThread中调用Looper.prepareMainLooper();

    ·
    一个Thread只有一个Looper对象,一个MessageQueue对象;Looper分发消息是阻塞式的(might
    block),即一个消息分发完成之后才会处理下一个消息。

    内存:

    ·
    Java虚拟机栈:线程私有的,其生命周期和线程一致,描述的是Java方法执行的内存模型。每个方法执行时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。(线程私有)

    ·
    Java堆:是虚拟机管理内存中最大的一块,被所有线程共享,该区域用于存放对象实例,几乎所有的对象都在该区域分配。Java堆是内存回收的主要区域,从内存回收角度看,由于现在的收集器大都采用分代收集算法,所以Java堆还可以细分为:新生代和老年代,再细分一点的话可以分为Eden空间、From Survivor空间、To Survivor空间等。根据Java虚拟机规范规定,Java堆可以处于物理上不连续的空间,只要逻辑上是连续的就行。(线程共享)

    网络:

    ·
    Socket 是对 TCP/IP 协议的封装,Socket
    只是个接口不是协议,通过
    Socket 我们才能使用
    TCP/IP 协议,除了
    TCP,也可以使用
    UDP 协议来传递数据。创建
    Socket 连接的时候,可以指定传输层协议,可以是
    TCP 或者
    UDP,当用
    TCP 连接,该Socket就是个TCP连接,反之。

    ·
    若双方是 Socket 连接,可以由服务器直接向客户端发送数据。若双方是
    HTTP 连接,则服务器需要等客户端发送请求后,才能将数据回传给客户端。

    ·
    http 为短连接,Socket为长连接。

    ·
    HTTP 的缺点:

    通信使用明文(不加密),内容可能会被窃听

    不验证通信方的身份,因此有可能遭遇伪装

    无法证明报文的完整性,所以有可能已遭篡改

    ·
    其他

    View:

    [图片上传中。。。(5)]

    ·
    调用requestLayout()的时候,会触发measure

    layout 过程,调用invalidate,会执行 draw
    过程。

    ·
    onTouch()和onTouchEvent()的区别:这两个方法都是在View的dispatchTouchEvent中调用,但onTouch优先于onTouchEvent执行。如果在onTouch方法中返回true将事件消费掉,onTouchEvent()将不会再执行。

    ·
    接收了ACTION_DOWN事件的函数不一定能收到后续事件(ACTION_MOVE、ACTION_UP)

    ·
    如果在某个对象(Activity、ViewGroup、View)的dispatchTouchEvent()消费事件(返回true),那么收到ACTION_DOWN的函数也能收到ACTION_MOVE和ACTION_UP。

    ·
    如果在某个对象(Activity、ViewGroup、View)的onTouchEvent()消费事件(返回true),那么ACTION_MOVE和ACTION_UP的事件从上往下传到这个View后就不再往下传递了,而直接传给自己的onTouchEvent()并结束本次事件传递过程。

    Window:

    [图片上传中。。。(6)]

    [图片上传中。。。(7)]

    ·
    MeasureSpec是一个32位整数,由SpecMode和SpecSize两部分组成,其中,高2位为SpecMode,低30位为SpecSize。SpecMode为测量模式,SpecSize为相应测量模式下的测量尺寸。View(包括普通View和ViewGroup)的SpecMode由本View的LayoutParams结合父View的MeasureSpec生成。

    SpecMode的取值可为以下三种:

    EXACTLY: 对子View提出了一个确切的建议尺寸(SpecSize);

    AT_MOST: 子View的大小不得超过SpecSize;

    UNSPECIFIED: 对子View的尺寸不作限制,通常用于系统内部。

    ·
    Draw顺序:绘制背景(drawBackground(canvas)),绘制自身内容(onDraw(canvas)),绘制子View(dispatchDraw(canvas)),绘制滚动条等(onDrawForeground(canvas))

    ·
    这也就是为什么我们在onCreate方法中调用view.getMeasureHeight()
    = 0的原因,我们知道activity.handleResumeActivity最后调用到的是activity的onResume方法,但是按上面所说在onResume方法中调用就可以得到了吗,答案肯定是否定的,因为ViewRootImpl绘制View并非是同步的,而是异步(Handler)

    ·
    ViewRootImpl也是有事件分发的。要知道,当用户点击屏幕产生一个触摸行为,这个触摸行为则是通过底层硬件来传递捕获,然后交给ViewRootImpl,接着将事件传递给DecorView,而DecorView再交给PhoneWindow,PhoneWindow再交给Activity,然后接下来就是我们常见的View事件分发了。

    ·
    WindowManager.LayoutParams中有三种类型,分别为

    应用程序窗口
    : type值在
    FIRST_APPLICATION_WINDOW ~ LAST_APPLICATION_WINDOW 须将token设置成Activity的token。eg:前面介绍的Activity窗口,Dialog

    子窗口:
    type值在
    FIRST_SUB_WINDOW ~ LAST_SUB_WINDOW SubWindows与顶层窗口相关联,需将token设置成它所附着宿主窗口的token。eg:
    PopupWindow(想要依附在Activity上需要将token设置成Activity的token)

    系统窗口:
    type值在
    FIRST_SYSTEM_WINDOW ~ LAST_SYSTEM_WINDOW SystemWindows不能用于应用程序,使用时需要有特殊权限,它是特定的系统功能才能使用。eg:
    Toast,输入法等。

    ·
    View 是 Android 中的视图的呈现方式,但是
    View 不能单独存在,它必须附着在
    Window 这个抽象的概念上面,因此有视图的地方就有
    Window。哪些地方有视图呢?Android
    可以提供视图的地方有
    Activity、Dialog、Toast,除此之外,还有一些依托
    Window 而实现的视图,比如
    PopUpWindow(自定义弹出窗口)、菜单,它们也是视图,有视图的地方就有 Window,因此
    Activity、Dialog、Toast等视图都对应着一个
    Window。这也是面试中常问到的一个知识点:一个应用中有多少个
    Window?

    ·
    前提

    线程&锁:

    ·
    synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中。

    ·
    对象锁是用来控制实例方法之间的同步,类锁是用来控制静态方法(或静态变量互斥体)之间的同步。

    ·
    java.util.concurrent.locks.Lock是一个类似于
    synchronized 块的线程同步机制。但是 Lock 比 synchronized 块更加灵活、精细,一般由ReentrantLock实现。

    ·
    一个 Lock 对象和一个
    synchronized 代码块之间的主要不同点是:

    synchronized 代码块不能够保证进入访问等待的线程的先后顺序。

    你不能够传递任何参数给一个
    synchronized 代码块的入口。因此,对于 synchronized 代码块的访问等待设置超时时间是不可能的事情。

    synchronized 块必须被完整地包含在单个方法里。而一个 Lock 对象可以把它的 lock()和
    unlock() 方法的调用放在不同的方法里。

    ·
    AtomicBoolean,AtomicInteger,AtomicLong

    ·
    AtomicReference 提供了一个可以被原子性读和写的对象引用变量。原子性的意思是多个想要改变同一个
    AtomicReference 的线程不会导致 AtomicReference 处于不一致的状态。AtomicReference还有一个
    compareAndSet() 方法,通过它你可以将当前引用于一个期望值(引用)进行比较,如果相等,在该
    AtomicReference 对象内部设置一个新的引用。

    ·
    其他

    ����}ZX��,3

    相关文章

      网友评论

          本文标题:Android面试笔记

          本文链接:https://www.haomeiwen.com/subject/yajolxtx.html