Android笔记大全(一)

题目

  • 在Activity启动的时候,去获取某个view的宽高,会发生什么事?如何处理?
  • 在onCreate中的setContenView(布局),如何获取该布局的实例?
    ViewGoup vg = getWindows().getDecorView().findViewById(android.R.id.content).getChildAt(0);
  • 自定义View?注意事项?
    1.尽量使用view.post,而不是handler
    2.动画及时停止,防止内存泄露
    3.避免大对象及大量变量的创建
  • View的绘制流程?
  • Activity的启动流程
  • Android的启动流程
  • 从A活动跳转到B活动,调用了哪些周期方法?(注意是否透明)
  • 在Activty中先start一个Service后,再bind时会回调什么方法?此时如何做才能回调Service的destory()方法?
  • Activity如何与Service进行通信?
    1.在Service中定义一个MyBinder类,该类集成Biner,在该类中声明交互的方法
    2.在Service的onBind的方法中返回该MyBinder(要声明)
    3.在Activity中实例化ServiceConnction类,重写他的onServiceConnction方法,在该方法中获取到Service的MyBind。
    4.在Activity中以BindService方法开启Service。
  • Fragment与Activity生命周期的区别
  • 谈一下AMS,启动流程?SystemUI什么时候启动?开机动画什么时候停止?
  • 如何删除SQLite中的一个字段?
  • SurfaceView和View的区别?
    1.SurfaceView是View基类派生出的类。
    2.View需要在UI线程对画面进行刷新,而SurfaceView可在子线程进行页面的刷新
    3.View适用于主动更新的情况,而SurfaceView适用于被动更新,如频繁刷新,这是因为如果使用View频繁刷新会阻塞主线程,导致界面卡顿
    4.SurfaceView在底层已实现双缓冲机制,而View没有,因此SurfaceView更适用于需要频繁刷新、刷新时数据处理量很大的页面
  • invalidate()和postInvalidate()的区别?
  • dp、dpi、px的区别?
    1.px:像素,如分辨率1920x1080表示高为1920个像素、宽为1080个像素
    2.dpi:每英寸的像素点,如分辨率为1920x1080的手机尺寸为4.95英寸,则该手机DPI为(1920x1920+ 1080x1080)½/4.95≈445dpi
    3.dp:密度无关像素,是个相对值
  • res目录和assets目录的区别?
    res中的文件都会被映射到R.java中,分配一个id,通过id获取。
    而assets中的文件需要通过AssetsManager获取
  • Android中的动画
    1.补间动画(View动画),可以使控件平移,伸缩,旋转,改变透明度。但不能真正改变控件的属性
    2.逐帧动画,将多个图片按顺序播放,形成的一种动画
    3.属性动画,真正能改变对象属性的动画,作用于对象。其通过反射技术获取属性的get和set方法,真正改变属性值。
  • 属性动画插值器和估值器的作用?
    插值器(Interpolator):
    根据时间流逝的百分比计算出当前属性值改变的百分比。确定了动画效果变化的模式,如匀速变化、加速变化等等。View动画和属性动画均可使用。
    常用的系统内置插值器:
    线性插值器(LinearInterpolator):匀速动画
    加速减速插值器(AccelerateDecelerateInterpolator):动画两头慢中间快
    减速插值器(DecelerateInterpolator):动画越来越慢
    类型估值器(TypeEvaluator):根据当前属性改变的百分比计算出改变后的属性值。针对于属性动画,View动画不需要类型估值器。
    常用的系统内置的估值器:
    整形估值器(IntEvaluator)
    浮点型估值器(FloatEvaluator)
    Color属性估值器(ArgbEvaluator)
  • Activity,PhoneWindow是如何被创建的?
    Activity是在在ActivityThread中在newAvtivity方法里通过ClassLoader创建的
    PhoneWindow是在ActivityThread的attach()方法中实例化的。是在创建Activity之后调用的。
  • Activity,Window和View的关系
    首先三者的关系是Activity > Window(PhoneWindow) > View。创建Activity之后,在启动过程中初始化了和绑定Window,Activity通过setContent()将View添加到Window中
  • AMS的启动流程
    在系统服务进程SystemServer中的ServerThread线程中run方法里启动,会调用AMS的静态main方法。该方法中创建一个线程等待ASM构造完成,同时,也初始化AcitivtyThread和ActivityStack。
  • 简述handle机制?阻塞原理?内存屏障?主线程耗时操作
  • Message的创建形式有哪些?
  • Handle的postDelay()会使消息队列发生什么变化?
  • 谈谈HandleThread
  • 谈谈ThreadLocal
  • 使用bindService创建IntentService会发生什么?
  • 线程池的优点、原理、类型?如何区别核心线程与非核心线程?如何保证核心线程不死?
  • LRU算法的原理?
  • Art和Dalvik和JVM的区别
  • 插件化开发
    当业务逻辑越来越复杂庞大的时候,一个应用中dex方法很可能会超过65536.这个时候就需要把其中一些分离出来插件化,它的表现形式有apk,jar或者dex文件等。我们需要动态加载这些文件,再通过反射获取该文件下的资源(图片),给宿主app使用。
    动态加载有两种类加载器:dexClassLoader和pathClassloader。
  • Fragment与Activity之间的交互
    Fragment与Activity之间的交互可以通过Fragment.setArguments(Bundle args)以及Fragment.getArguments()来实现。
  • 热修复技术原理
  • 图片的三级缓存
  • Debug和Release状态的不同
  • MVC、MVP、MVVM应用和彼此本质区别
  • Broadcast的分类?
    广播可以分为有序广播、无序广播、本地广播、粘性广播。其中无序广播通过sendBroadcast(intent)发送,有序广播通过sendOrderedBroadcast(intent)发送。
    有序广播。
    (1) 有序广播可以用priority来调整优先级,取值范围-1000~+1000,默认为0,数值越大优先级越高,优先级越高越优先获得广播响应。同步广播
    (2) abortBroadcast()可来终止该广播的传播,对更低优先级的屏蔽,注意只对有序广播生效。
    (3) 有序广播在传播数据中会发生比如setResultData(),getResultData(),在传播过程中,可以从新设置数据
    本地广播是通过LocalBroadcastManager内置的Handler来实现的,只是利用了IntentFilter的match功能,至于BroadcastReceiver 换成其他接口也无所谓,顺便利用了现成的类和概念而已。在register()的时候保存BroadcastReceiver以及对应的IntentFilter,在sendBroadcast()的时候找到和Intent对应的BroadcastReceiver,然后通过Handler发送消息,触发executePendingBroadcasts()函数,再在后者中调用对应BroadcastReceiver的onReceive()方法。
    粘性消息:粘性消息在发送后就一直存在于系统的消息容器里面,等待对应的处理器去处理,如果暂时没有处理器处理这个消息则一直在消息容器里面处于等待状态,粘性广播的Receiver如果被销毁,那么下次重建时会自动接收到消息数据。(在 android 5.0/api 21中deprecated,不再推荐使用,相应的还有粘性有序广播,同样已经deprecated)

  • 数据库如何进行升级?SQLite增删改查的基础sql语句?
    在SQLiteOpenHelper的构造函数中,包含了一个version的参数。这个参数即是数据库的版本。 所以,我们可以通过修改version来实现数据库的升级。 当version大于原数据库版本时,onUpgrade()会被触发,可以在该方法中编写数据库升级逻辑
    增:INSERT INTO table_name (列1, 列2,…) VALUES (值1, 值2,….)
    删: DELETE FROM 表名称 WHERE 列名称 = 值
    改:UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
    查:SELECT 列名称(通配是*符号) FROM 表名称

  • Retrofit CreateApi实现原理

  • EventBus实现原理

  • requestLayout,invalidate,postInvalidate区别与联系
  • Activity的onNewIntent
  • 微信小程序实现原理
  • adb常用命令行
  • Glide缓存源码,加载原理
  • RecyclerView与ListView(缓存原理,区别联系,优缺点)
  • 组件化实现方案,路由原理

  • 简述GreeDao原理

  • 冷启动和热启动
  • AIDL的使用和原理

  • 为什么Intent(或者说Bundle)中携带的数据需要支持序列化呢?
    因为Intent支持进程间的通信,而进程间的通信又仅支持几种基本的数据类型和序列化的类型,所以Intent传递的数据要支持序列化

  • SharedPreferences数据存储的apply()和commit()区别

  • bitmap如何处理大图,如一张30M的大图。一张200k的图片为什么会oom?

  • Android相关优化(如内存优化、网络优化、布局优化、电量优化、业务优化)
  • EventBus实现原理和观察者模式在开发中的运用?

  • IntentFilter的匹配规则
    在AndroidMinifast中注册一个Activity、Service、Broadcast时,可以给组件添加

  • 在handlerThread中获取的looper时是如何保持同步的?
    创建looper是在run方法下进行的,此时获取looper会用getlooper()来获取looper,当looper为空时getLopper会调用wait(),一旦在run方法下创建好looper,则会notifyAll(),结束wait的线程。此时获取looper就不为空了。
  • 估值(TypeEvator)器原理
    起始值+fraction*(结束值-起始值)
  • ThreadLocal的原理
    ThreadLocal内部用一个Map来储存该线程下的资源。Map的key为当前线程的实例,value则是储存的值。访问该线程,实质上就是访问该线程下的已经储存好的资源。
  • Handler如何实现线程切换的
    例如现在有A、B两个线程,在A线程中有创建了handler,然后在B线程中调用handler发送一个message。
    当在A线程中创建handler的时候,同时创建了MessageQueue与Looper,Looper在A线程中调用loop进入一个无限的for循环从MessageQueue中取消息,当B线程调用handler发送一个message的时候,会通过msg.target.dispatchMessage(msg);将message插入到handler对应的MessageQueue中,Looper发现有message插入到MessageQueue中,便取出message执行相应的逻辑,因为Looper.loop()是在A线程中启动的,所以则回到了A线程,达到了从B线程切换到A线程的目的。
  • getMeasureWidth()和getWidth()的区别
  • dex文件的加载原理?
  • Binder原理?实现模型?如何使用?
  • ViewRootImpl的requestLayout()与view的requestLayout()的区别?
    view.requestLayout() -> ViewPatent.requestLayout() -> ViewRootImpl.requestLayout();
  • Activity的事件是谁传递的?
    底层硬件 -> ViewRootImpl.disPatchInputEvent封装放入队列处理,队列循环分发 -> DecorView.disPatchTouchEvent() -> window.callback.dispatchTouchEvent() -> Activity.dispatchTouchEvent() -> window.superDispatchTouchEvent() -> DecorView.superDispatchTouchEvent() -> ViewGoup
  • MultiDex原理及优化方式
    1.开启MultiDex模式,编译出含多个dex的apk
    2.安装
    2.1:MultiDex类install方法,5.0以下不支持
    2.2:5.0以上交由MultidexExtrator去加载非主dex
        2.2.1:先读取缓存的dex文件,无缓存的话就从apk中重新解压获取(耗时大)
        2.2.2:将读取到的多个dex文件压缩成zip压缩包(耗时大),对应的对象为ExtractedDex,并放进一个压缩列表中List<ExtractedDex>
    2.3: 利用反射获取到ClassLoader的DexPathList对象,获取DexPathList的makeDexElements方法,将上一步的压缩列表传进该方法中,生产Element数组
    2.4: 将非主dex产生的Element数组,加入到主Dex产生的Element数组中(尾插法),最终生成一个完成的Element数组
    2.5: 上一步生成的数组由ClassLoader(BaseDexClassLoader)的findclass方法进行遍历,拿到DexFile对象,通过DexFile对象的native方法(loadClassBinaryName)生成Class对象
    
  • 如何获取启动时间?
    指令:adb shell am start -W [pag+activity]
    埋点
  • ASM插桩原理
    1.继承Transform自定义一个Gradle插件。在transform()方法下获取transformInput列表,该列表分别包含了文件夹(Directory)下的.class和jar下的.class,遍历获得该列表
    2.将获取到的class交给ASM处理。即ClassReader和ClassWriter,然后交给Visitor,Visitor在visiMethod()方法下判断是否为目标class,是的话再交给MethodVisitor进行内容插入。visitCode()方法内插入想要埋点的内容,visitInsn()方法为方法结束时埋点内容。
    关于字节码内容修改,可利用ASM Bytecode Outline插件
    
    3.修改完成后得到ClassWriter交给FileOutputStream修改写入byte流,完成替换
    4.又dx/d8打包.dex文件,继续接下来的生成apk任务
  • handle的底层原理?Handle如何阻塞的?
  • 为什么Application下的R.java的资源id是final的,而libs下的R.java的资源id是非final的?
  • apk的安装原理
  • 怎么检查内存泄漏?
  • Launcher如何启动应用的?
  • CordinateLayout原理?如何实现滚动的?
  • 识别一个字符串是否是ipv4地址
  • Android中的注解有哪几种
  • WindowManager的addView()与ViewGoup的addView()有什么区别?
  • APK是如何被解析的?
  • 单元测试
  • so是如何被加载的?生命周期是怎么样的?
  • native怎么检测内存泄漏?
  • IO优化
  • mmap
    https://www.cnblogs.com/huxiao-tee/p/4660352.html
  • B数/B+数
  • wrap_content如何计算的?
  • 跨进程传递大内存数据如何做?
    https://www.jianshu.com/p/9b4cfafe069e
  • 如何加入点击事件?如何添加长按事件?事件优先级?
  • RxJava处理异常错误,线程切换原理?
  • 加密?签名?对称加密?非对称加密?MD5?SHA1?
  • okio的原理?与原生javaIO对比优点在哪里?
  • 储存优化措施?
    sp缺点、文件io、sqlite
  • sqlite的锁机制
  • Android开机动画的启动/关闭流程?如何替换开机动画?
  • Zygote的fork的过程?
  • okHttp的缓存策略、连接复用、okio
    https://www.jianshu.com/p/5249eed1cc53
  • 简单工厂、方法工厂、抽象工厂
  • 生产者&消费者模式
  • https://blog.csdn.net/qq_17250009/article/details/52175211
  • Binder驱动原理
    http://gityuan.com/2015/10/31/binder-prepare/
    http://gityuan.com/2016/09/04/binder-start-service/
    https://www.jianshu.com/p/adaa1a39a274
  • 如何获取ANR信息后上传服务器?
    https://blog.csdn.net/codezjx/article/details/78648333
    1. 什么时候获取信息?
        根据源码当发生ANR时,首先会调用AMS的appnotResponeing方法,会优先dump出当前进程栈信息,设置ANR标记,dumpStackTraces方法记录info信息,调用makeAppNotRespondingLocked方法生成ProcessErrorState对象。
        dumpStackTraces时会通过FileObserver监听写入操作。
        所以我们需要用FileObserver来监听app/anr目录即可,并筛选traces文件,就能知道此时发生了ANR.
    2. 去哪里获取信息?
        根据源码知道ANR时最终会产生ProcessErrorStateInfo对象,该对象可通过ActivityManager的getProcessInErrorState方法进行跨进程通信,返回ProcessErrorStateINfo对象列表,通过当前进程信息设置condition筛选出自己进程的ProcessErrorState即可。
    
  • select、poll和epoll
    https://www.cnblogs.com/aspirant/p/9166944.html
    select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。而epoll其实也需要调用epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在epoll_wait中进入睡眠的进程。虽然都要睡眠和交替,但是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的时候只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。这就是回调机制带来的性能提升。
  • Retrofit原理?