android面试2019

本人菜鸟一个,哪里有错误,欢迎指出啊!多谢!!!

  • 阿里的android开发手册
  • 一、activity
    • 1、activity作用
    • 2、activity生命周期
    • 3、activity四种启动模式
    • 4、activity启动流程
    • 5、如何加速启动actviity
    • 问题:AActivity启动BActivity,此时B启动模式为singleTask并且有实例存在栈中,此时的B的生命周期?
  • 二、fragment
    • 1、fragment作用
    • 2、fragment生命周期
    • 3、fragment的回退栈
  • 三、service
    • 1、service作用
    • 2、service的两种启动方式和生命周期
    • 3、service与activity的两种通信方式
    • 4、IntentService
    • 5、service保活
  • 四、ContentProvider(内容提供者)
  • 五、BroadcastReceiver(广播)
    • 1、作用域
        • 全局广播
        • 本地广播
    • 2、两种注册方式
        • 静态注册
        • 动态注册
    • 3、广播类型
        • 有序广播
        • 无序广播
  • 六、http协议流程
  • 七、网络请求原理及框架
  • 八、数据解析框架
  • 九、三大图片加载框架对比
      • 图片的三级缓存
      • 总结
      • 加载超长图
  • 十、屏幕适配
  • 十一、RecyclerView优化
      • 重点:不能在adapter中修改控件的一些属性,要从数据源上改变。因为RecyclerView的回收复用机制,取出来时会进行初始化属性
      • RecyclerView与ListVIew和GridView最大的区别:recyclerView可扩展性强,也就是自定义布局管理器(layoutManager)
      • 设置recyclerView的item之间间距不一样,使用ItemDecoration(分割线:多组标题吸顶可以使用)
      • 控制item的增删动画使用itemAnimator
      • 想要设置点击或长点击事件,需要自己写
        • getChildCount()是当前屏幕看到的子项数,getItemCount()是该RecyclerView总共的子项数
  • 十二、内容泄漏导致内存溢出(oom)
      • 1、导致内存泄漏的情况及解决方法
  • 十三、插件化与组件化
      • 1、插件化
      • 2、组件化
  • 十四、热更新与增量更新
      • 1、热更新主要用于紧急修复bug
      • Sophix与Tinker比较
      • 2、增量更新主要用于增加产品功能
  • 十五、Handler机制
      • 1、handler作用
      • 2、handler流程
  • 十六、三种动画
      • 1、插值器(Interpolator)
      • 2、类型估值器(TypeEvaluator)
  • 十七、Activity、View、Window三者之间的关系?
  • 十八、Seralizable与Parcelable
  • 十九、app性能优化
  • 二十、android保证网络安全
        • 加密+Https
  • 二十一、AIDL跨进程通信
        • binder与socket、管道、共享内存区别
  • 二十二、android版本6.0~9.0适配
  • 二十三、android的多线程几种方式
  • 持续更新中...

阿里的android开发手册

一、activity

1、activity作用

前台运行页面,用户可见、可操作。不能进行耗时操作。5s后会产生ANR

2、activity生命周期

onCreate()-onStart()-onResume()-onPause()-onStop()-onDestroy()-onRestart()
onCreate:用户首次创建activity时
onStart:可见,无法与用户交互,没有焦点,用来做一些动画的初始化
onResume:当activity位于前台可供用户操作时,此时activity位于栈顶。可用来视频的继续播放
onPause:当另一个activity覆盖当前的activity时,可见,无法与用户交互。按回退键,再次执行onResume()
onStop:不可见,在系统内存紧张的情况下,有可能会被系统进行回收。所以可做资源回收工作。
onDestroy:可通过finish()销毁activity时
onRestart:app从后台返回前台时

3、activity四种启动模式

standard(默认模式):
无论当前要打开的activity实例是否在栈顶,总是new activity实例。各个实例可以属于不同的 task,一个 task 中也可以存在多个实例。
singleTop:
当前要打开的activity实例存在于栈顶时,会复用该activity实例。否则new activity实例。
singleTask:
当前要打开的activity实例只要存在该栈中,就会复用该activity实例,同时位于该activity实例上面的其他activity实例都会被移出该栈,这个时候按返回键,别移出的activity页面将不再显示,除非重新打开该activity页面创建实例。
singleInstance:
当前要打开的activity实例只要存在于整个手机的堆中,就会复用。否则会在堆中创建新的实例

4、activity启动流程

转载:详细解读activity启动流程中的各种进程的作用

5、如何加速启动actviity

1、减少onCreate()时间,减少初始化的操作,避免耗时操作
2、布局文件优化。减少层级结构、多使用include、merge等标签复用布局
3、在启动过程中有时会出现白屏、闪屏等情况,自定义一个主题在AndroidManifest.xml中设置上

问题:AActivity启动BActivity,此时B启动模式为singleTask并且有实例存在栈中,此时的B的生命周期?

答:会走onNewIntent->onStart->onResume
/***************************************************************************/

二、fragment

1、fragment作用

1、可以在程序运行时动态的切换(添加、替换、隐藏),并且比activity流畅,提高性能
2、可以动态创建不同尺寸的页面,也容易适配平板
3、依赖于activity,可以重用
4、可以传值也可以接受回传

2、fragment生命周期

onAttach()-onCreate()-onCreateView()-onActivityCreated()
-onStart()-onResume()-onPause()-onStop()
-onDestroyView()-onDestroy()-onDetach()-onRestart()

3、fragment的回退栈

如果你不是手动开启回退栈,它是直接销毁再重建,但如果将Fragment任务添加到回退栈,它就有了类似Activity的栈管理方式。
/***************************************************************************/

三、service

1、service作用

后台运行服务,不提供页面呈现。不能进行耗时操作。20s后会产生ANR

2、service的两种启动方式和生命周期

startService()和bindService()
android面试2019_第1张图片

3、service与activity的两种通信方式

1、BindService实现serviceConnection接口
重写onServiceConnected(判断是否连接上,需返回一个IBinder实例)和onServiceDisconnected(只在Service 被破坏了或者被杀死的时候调用)方法
2、广播+startService

4、IntentService

HandlerThread:轻量级异步类,继承Thread,内部封装了Looper。因为子线程中没有Looper需要自己手动创建。
IntentService:Service+HandlerThread,自动开启线程,可以执行一些耗时任务,用完自动停止。防止出现ANR错误

5、service保活

service的优先级
1、前台进程
2、可见进程
3、服务进程
4、后台进程
5、空进程
【1】提高优先级我们可以使用startForeground()方法将Service设置为前台进程。
【2】双进程守护
创建主服务——创建守护服务
在继承service重载onStartCommand方法中返回各个参数的意义
START_STICKY:在Service被关闭后,重新开启Service
START_NOT_STICKY:服务被异常杀掉后,系统将会被设置为started状态,系统不会重启该服务,直到startService(Intent intent)方法再次被调用。
START_REDELIVER_INTENT:重传Intent,使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
【3】继承JobService来实现应用退出后重启service,类似守护进程
【4】保证Service在开机后自动启动
注册广播——开机启动广播
android面试2019_第2张图片
/***************************************************************************/

四、ContentProvider(内容提供者)

主要用在多个进程间存储和读取数据
fileProvider继承自ContentProvider
/***************************************************************************/

五、BroadcastReceiver(广播)

不能进行耗时操作。10s后会产生ANR

1、作用域

全局广播

多个进程都可以接收到

本地广播

只能在本进程内接收到

2、两种注册方式

静态注册

在AndroidManifest.xml文件中注册。
静态注册的广播,即使Activity销毁了,仍然可以收到广播。即使杀死进程,仍然可以收到广播

动态注册

java动态代码注册
动态注册的广播会受Activity的生命周期的影响, 当Activity销毁的时候,广播就失效了

3、广播类型

有序广播

Context.sendOrderedBroadcast()来发送一条有序的广播。从优先级高的开始,依次往下广播。获取上个广播返回的结果getResult()

无序广播

用Context.sendBroadcast()来发送一条无序广播。没有getResult()方法
/***************************************************************************/

六、http协议流程

1、域名解析
2、TCP三次握手
3、建立连接后发起请求
4、服务端响应请求,返回给浏览器数据
5、浏览器解析html代码,同时请求资源(图片)
6、浏览器进行渲染
7、TCP四次挥手
/***************************************************************************/

七、网络请求原理及框架

关于 HTTP 请求报文和响应报文的格式这里就不再过多介绍了,简单说,HTTP 协议是以 ASCII 码传输,建立在 TCP/IP 协议之上的应用层规范。规范把 HTTP 请求分为三个部分:请求行、请求头、请求体。类似于:

<空格> <协议版本号> <回车> <换行符>
<请求头>
<请求体>

Volley VS OkHttp
Volley 的优势在于封装的更好,而使用 OkHttp 你需要有足够的能力再进行一次封装。而 OkHttp 的优势在于性能更高,因为 OkHttp 基于 NIO 和 Okio ,所以性能上要比 Volley更快。
Retrofit是在okHttp基础上封装好的,当然Retrofit更好一些。
主流网络架构
Retrofit + OkHttp + RxJava + Dagger2
/***************************************************************************/

八、数据解析框架

1、json-lib(原生)
需要依赖很多jar包,对于复杂类型的bean的转换也很容易出错,pass
2、jackson
优点:依赖的jar包较少,简单易用,性能较高,社区比较活跃,更新速度快。
缺点:全部解析。无论是json转bean,对于复杂的数据类型,容易出错。bean转json不是标准的json格式数据。依赖包较大
3、Goolge的Gson
优点:按需解析,无需jar包,直接导入依赖,前提是需要创建好对应的bean。无论是json转bean,还是bean转json都无可挑剔。
缺点:性能比fastJson差点
4、阿里的fastJson
优点:按需解析,无需jar包,直接导入依赖,性能最好的json解析框架
缺点:bean转json有时会出现一些问题。
总结
1、可以考虑Gson与fastJson一起使用
在解析(json转bean)时用fastJson,在需要bean转json时使用Gson
2、数据量小时采用Gson,大采用fastJson
3、依赖包体积由小到大:Gson /***************************************************************************/

九、三大图片加载框架对比

1、Glide
优点:1、可以绑定生命周期,不仅可以传入Context还可以传入Activity和Fragment。
2、Glide加载的是与控件大小一样尺寸的图片即RGB_565,减小内存的开销
缺点 :体积大
2、Picasso
优点:体积小
缺点:1、加载的是全尺寸即ARGB_8888,内存开销较大
2、生命周期只能传入Context
3、Fresco
优势:在5.0的系统下,它会将图片放在一个特别的内存区域(Ashmem区),当图片不显示的时候,占用的内存会自动释放,减少了oom情况的发生
缺点:在5.0系统以后,系统默认将图片储存在Ashmem区域,导致优势全没

图片的三级缓存

一级缓存:手机的运行内存
二级缓存:手机的磁盘(文件)
三级缓存:网络加载(流)
首先会先从一级缓存中加载,如果没有再从二级缓存中加载,还没有去网络缓存中加载,没有就请求接口得到数据
LruCache策略:在一级缓存中通常会设置一个储存容量最大值,一旦达到这个容量,就要进行释放一些使用次数较少的图片,达到避免产生oom的特殊情况

总结

Picasso能做的Glide也都可以,并且Glide可以加载GIF动态图。Glide适用处理一些较大的图片流。

加载超长图

1、获取到图片的宽高,在使用SubsamplingScaleImageView框架(底层基于BitmapRegionDecoder)进行图片分段显示
2、压缩显示。设置固定宽高尺寸
/***************************************************************************/

十、屏幕适配

android面试2019_第3张图片
1、最简单的dp适配
描述:不能很好的适配平板之类的宽屏
2、宽高限定符
描述:按一定的宽高,分段适配,不是很精确,需要增加很多的文件
3、最小宽度限定符
描述:按一定的宽,分段适配,精确,需要增加很多的文件
4、鸿洋的按屏幕的宽高比,动态修改视图宽高
描述:如果是自定义的view也会有所影响
5、今日头条保持dp(设计图总宽)不变,动态改变density(1dp占当前多少像素)px = density * dp
描述:全局修改 density,对于第三方布局有所影响
今日头条的AndroidAutoSize
/***************************************************************************/

十一、RecyclerView优化

重点:不能在adapter中修改控件的一些属性,要从数据源上改变。因为RecyclerView的回收复用机制,取出来时会进行初始化属性

RecyclerView与ListVIew和GridView最大的区别:recyclerView可扩展性强,也就是自定义布局管理器(layoutManager)

设置recyclerView的item之间间距不一样,使用ItemDecoration(分割线:多组标题吸顶可以使用)

控制item的增删动画使用itemAnimator

想要设置点击或长点击事件,需要自己写

getChildCount()是当前屏幕看到的子项数,getItemCount()是该RecyclerView总共的子项数

1、RecyclerView设置横向滑动时,item居中,带有惯性
new LinearSnapHelper().attachToRecyclerView(mRecyclerView);
2、RecyclerView设置横向滑动时,item居中,效果类似ViewPager
new PagerSnapHelper().attachToRecyclerView(mRecyclerView);
3、ScrollView嵌套RecyclerView滑动冲突
1)代码设置
mRecyclerView.setHasFixedSize(true);确保每个item的宽高都是一定的,减少计算每个item的宽高
mRecyclerView.setNestedSrollingEnabled(false);阻止本身的滑动
2)业务设置
根据滑动的方向判断哪个事件消费,onInterceptTouthEvent()进行事件拦截
4、数据优化
1)分页加载,将数据缓存,提高二次加载的速度。
2)对于新增与删除的数据通过DiffUtil来进行局部刷新DiffUtil用来判断新数据与旧数据的差别,从而进行局部刷新
5、布局优化
1)减少item的绘制层级
2)共用RecycledViewPool线程池
3)RecyclerView数据预取
4)加大RecyclerView的缓存用空间换时间,提高流畅度
5)处理刷新时屏幕闪烁((DefaultItemAnimator)mRecyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
/***************************************************************************/

十二、内容泄漏导致内存溢出(oom)

1、导致内存泄漏的情况及解决方法

1)没有使用的图片,没有进行释放
2)非静态内部类和匿名内部类持续持有外部类,导致外部类无法被GC回收
问题:比如Handler、AsycnTask等。
解决:1、改为静态内部类+软引用>弱引用>虚引用
2、Handler:removeCallbacksAndMessages(null)
3)静态变量引用内部类
问题:静态对象引用了方法内部类,方法内部类也是持有Activity实例的,会导致Activity泄漏
解决:就是通过在onDestory方法中置空static变量
4)使用较多的单例模式
问题:单例模式的生命周期与程序的生命周期一致,不能传入activity的生命周期
解决:传入application的生命周期getApplicationContext()
5)关闭activity时广播未取消注册
解决:在activity的onDestroy()方法中取消注册广unregisterReceiver()
6)弱网进行网络请求
问题:在弱网情况下就会导致接口回调缓慢,这时用户很可能就会退出Activity不在等待,但是这时网络请求还未结束,回调接口为内部类依然会持有Activity的对象,这时Activity就内存泄漏的,并且如果是在Fragment中这样使用不仅会内存泄漏还可能会导致奔溃。
解决:这类异常的原理和非静态内部类相同,所以可以通过【static内部类+弱引用进行处理。】由于本例是通过Retrofit进行,还可以【在onDestory进行call.cancel进行取消任务,】也可以避免内存泄漏。
7)Rxjava
问题:consumer这个为内部类,如果异步任务没有完成Activity依然是存在泄漏的风险的。
解决:RxJava有取消订阅的方法,在activity的onDestroy()方法中
if (disposable!=null && !disposable.isDisposed()){
disposable.dispose();
}
8)service用完也要停止服务
stopself();
/***************************************************************************/

十三、插件化与组件化

1、插件化

1、可以在一个APP内做到免安装运行另一个app内的activity
2、hook插桩动态将只注册没有具体类的activity替换为另一个app内的实体activity
3、可以做到类似热更新
4、子moduel可单独运行,也可插到宿主上运行

2、组件化

1、按业务分不同的library或module,可以设置参数true或false更改为module或library,module可以单独运行,library不可单独运行,但是最终发布的时候是将这些组件(library)合并统一成一个apk
2、组件之间的跳转用Router框架
/***************************************************************************/

十四、热更新与增量更新

1、热更新主要用于紧急修复bug

原理:在一个数组中存着.dex文件,将新类转换成.dex文件并在加载之前经信的.dex文件放在数组第一位,开始加载时会先加载新类,就不会再加载旧类,完成了修改更新
热更新框架对比

方案对比 Sophix Tinker nuwa AndFix Robust Amigo
类替换 yes yes yes no no yes
So替换 yes yes no no no yes
资源替换 yes yes yes no no yes
全平台支持 yes yes yes no yes yes
即时生效 同时支持 no no yes yes no
性能损耗 较少 较小 较大 较小 较小 较小
补丁包大小 较小 较大 一般 一般 较大
开发透明 yes yes yes no no yes
复杂度 傻瓜式接入 复杂 较低 复杂 复杂 较低
Rom体积 较小 Dalvik较大 较小 较小 较小
成功率 较高 较高 一般 最高 较高
热度
开源 no yes yes yes yes yes
收费 收费(设有免费阈值) 收费(基础版免费,但有限制) 免费 免费 免费 免费
监控 提供分发控制及监控 提供分发控制及监控 no no no no

Sophix与Tinker比较

阿里的Sophix收费的阈(yu`)值
同一个账号中多个app合计的月活跃设备在10万以下免费,对于项目初期够用了
1、Sophix比较简单,而且对代码无侵入,好维护好操作易上手;(采用新理念性能消耗低)
Tinker接入很复杂,代码入侵,性能消耗很高,要合成资源,而且不支持即时生效
我的建议
我建议用Sophix,性能消耗低,支持即时生效,最主要的是对代码无侵入,便于代码的维护,以后的版本迭代,新功能的接入都不收影响。而且免费阈值对项目初期够用了。

2、增量更新主要用于增加产品功能

原理:通过生成差分包的供下载,再合并达到更新的方式
详情:https://www.jianshu.com/p/f1f9d1c8bb4e
/***************************************************************************/

十五、Handler机制

1、handler作用

在子线程与主线程之间通讯。在子线程中发送消息,在主线程中处理消息。

2、handler流程

1、Handler.sendMessage()发送message到MessageQueue队列中(通过enqueueMessage()加入到链表对应的位置)
2、Looper通过loop()开始不停的从MessageQueue中取出message(MessageQueue.next()不是消息阻塞,是异步阻塞IO)
3、调用message绑定的Handler对象(disptchMessage())交给发送该消息的Handler处理
4、如果是post发送的消息,直接在post()括号中new一个匿名Runnable处理事件。否则会调用我们复写的handlerMessage()进行处理
5、处理完成后会调用Message.recycle()将message放入对象池中,等待下次复用。
6、三者就形成了一个闭环
/***************************************************************************/

十六、三种动画

这里我主要写一下插值器估值器

1、插值器(Interpolator)

根据时间流逝的百分比计算出当前属性值改变的百分比。确定了动画效果变化的模式,如匀速变化、加速变化等等。View动画和属性动画均可使用。常用的系统内置插值器:
1、线性插值器(LinearInterpolator):匀速动画
2、加速减速插值器(AccelerateDecelerateInterpolator):动画两头慢中间快
3、减速插值器(DecelerateInterpolator):动画越来越慢

2、类型估值器(TypeEvaluator)

根据当前属性改变的百分比计算出改变后的属性值。针对于属性动画,View动画不需要类型估值器。常用的系统内置的估值器:
1、整形估值器(IntEvaluator)
2、浮点型估值器(FloatEvaluator)
3、Color属性估值器(ArgbEvaluator)
/***************************************************************************/

十七、Activity、View、Window三者之间的关系?

activity创建一个window,在window上展示view
/***************************************************************************/

十八、Seralizable与Parcelable

区别 Serializable Parcelable
所属API JAVA API Android SDK API
原理 序列化和反序列化过程需要大量的I/O操作 序列化和反序列化过程不需要大量的I/O操作
开销 开销大 开销小
效率 很高
使用场景 序列化到本地或者通过网络传输 内存序列化

Seralizable
Seralizable相对Parcelable而言,好处就是非常简单,只需对需要序列化的类class执行就可以,不需要手动去处理序列化和反序列化的过程,但需要进行大量的IO操作
Parcelable
1、Parcelable是android特有的序列化API,它的出现是为了解决Serializable在序列化的过程中消耗资源严重的问题,但是因为本身使用需要手动处理序列化和反序列化过程,会与具体的代码绑定,使用较为繁琐。
2、而Parcelable依赖于Parcel,Parcel的意思是包装,实现原理是在内存中建立一块共享数据块,序列化和反序列化均是操作这一块的数据,如此来实现。
/***************************************************************************/

十九、app性能优化

反应快、稳定、省电、apk体积小
1、反应快
1)布局优化:减少层级嵌套。避免页面结构复杂化。include、marge复用布局。
2)数据优化:避免在onCreate()中初始化大量数据。请求大量数据时分页加载
3)内存优化:避免在主线程中进行耗时操作,可以采用异步执行。减少内存的占用,将无用的图片、变量和对象进行释放,可以采用静态内部类+软引用/弱引用。
4)启动优化:
app启动流程:
1、Launcher所在的进程通过ActivityManagerProxy(代理对象)将工作交给ActivityManagerService,它来启动app并保存首先要启动activity
2、如果已经启动,就直接开启,否则就通过Zygote进程fork自身,启动一个新进程创建ActivityThread,启动其中的main函数(该线程相当于主线程)
3、在主线程中,将首先要启动activityd给到ActivityManagerService,
4、ActivityThread随后依次调用Looper.prepare()和Looper.loop()来开启消息循环.
5、通过ActivityThread把新建的进程和Application绑定,然后加载app的classes到内存中
6、启动 Activity。
【1】闪屏页优化
在AndroidManifest.xml中自定义一个全局主题,将闪屏那个页面替换自己的logo,通过属性android:windowBackground这样打开桌面图标会马上显示logo,不会出现黑/白屏,直到Activity启动完成,替换主题,logo消失,但是总的启动时间并没有改变。
【2】MultipDex优化
multiDexEnabled true:表示app内的方法数可以突破65536,一个dex装不下,用多个dex来装。MultipDex主要为了支持5.0以下的手机

Android 5.0以下,ClassLoader加载类的时候只会从class.dex(主dex)里加载,ClassLoader不认识其它的class2.dex、class3.dex、…,当访问到不在主dex中的类的时候,就会报错:Class NotFound xxx

如果虚拟机本身就支持加载多个dex文件,那就啥都不用做;如果是不支持加载多个dex(5.0以下是不支持的),则走到 doInstallation 方法。是比较耗时的。

一种是直接在闪屏页开个子线程去加载dex,难维护,不推荐;
ContentProvider初始化太早了,如果不在主dex中,还没启动闪屏页就已经crash了
一种是今日头条的方案,在单独一个进程加载dex,加载完,主进程再继续。
在另一个进程中加载dex,加个弹窗加载中,在视觉上会感觉启动变快了,其实时间没什么变化
【3】第三方库懒加载
第三方框架初始化可以在用到时在进行初始化,也就是懒加载。没有必要一定在application中进行加载。【异步进行加载】待确定
【4】卡顿优化
VSYNC 这个概念出来很久了,Vertical Synchronization,就是所谓的“垂直同步”。在 Android 中也沿用了这个概念,我们也可以把它理解为“帧同步”。为了保证 CPU、GPU 生成帧的速度和 Display 刷新的速度保持一致。

Android 系统每 16ms(更准确的是大概16.6ms) 就会发出一次 VSYNC信号触发 UI 渲染更新。大约屏幕一秒刷新60次,也就是说要求 CPU 和 GPU 每秒要有处理 60 帧的能力,一帧花费的时间在 16ms 内。如果超出这个时间就回出现卡顿。
卡顿产生的原因
1、布局页面复杂:渲染时间增加
2、过度绘制:绘制了多重背景或者绘制了不可见的UI元素.
3、主线程的复杂运算,耗时运算
4、频繁的GC:执行 GC 操作的时候,任何线程的任何操作都会需要暂停,等待 GC 操作完成之后,其他操作才能够继续运行, 故而如果程序频繁 GC, 自然会导致界面卡顿
解决:尽量不要在循环中大量的使用局部变量。防止同时创建大量的对象或变量

内存泄漏检测工具:LeakCanary
2、稳定
1、也就是不崩溃,可以进行try/catch进行捕获,最好是全局捕获线程异常,全局监控
2、避免产生ANR无响应,就是避免在主线程中执行耗时任务。
3、LMK:android的沙箱机制,每个应用程序都运行在一个独立的进程中,各自拥有独立的Dalvik虚拟机实例,系统默认分配给虚拟机的内存是有限度的。当系统内存太低依然会触发LMK(Low Memory Killer)机制,即出现闪退、崩溃现象。Android4.0以后,可以通过在application节点中设置属性android:largeHeap=”true”来设置最大可分配多少内存空间就可以突破一定限制。
3、省电
1、减少浮点运算
2、使用 Job Scheduler 管理后台任务。
4、apk体积小
1、开启混淆、压缩、去除多余的资源
2、压缩图片
3、避免引入无用的第三方库
/***************************************************************************/

二十、android保证网络安全

加密+Https

1、不可逆: MD5、sha1
概念:没有办法逆向回推(MD5目前可以暴力解开)
2、对称加密: DES、AES(建议使用)
概念:用同一个密钥对数据进行加密/解密
对比:DES的密钥长度是56位,不安全。AES的密钥长度最少是128位,建议使用256位
3、非对称加密: RSA
概念:用公钥加密,用私钥解密。注意密钥长度不要低于512位,建议使用2048位的密钥长度
结合使用
1、用AES对数据进行加密
2、用RSA对AES的密钥进行加密
3、用https://…进行请求
/***************************************************************************/

二十一、AIDL跨进程通信

AIDL是Android Interface Definition Language 的缩写。意思是Android接口定义语言。

1、服务端:服务端就是你要连接的进程。他提供给客户端一个Service,在这个Service中监听客户端的连接请求,然后创建一个AIDL接口文件,里面是将要实现的方法,注意这个方法是暴露给客户端的的。最后在Service中实现这个AIDL接口即可(这里是接口的具体实现)。服务端的职责是提供连接和自身

2、客户端:客户端首先需要绑定服务端的Service,绑定成功后,将服务端返回的Binder对象转换成AIDL接口所属的类型,最后调用AIDL的方法就可以了。可以看到,客户端还是比较简单的,负责连接和调用。

想让自己的Aapp得到Bapp数据,就需要选定Bapp作为服务端,Aapp作为客户端,一个服务端可以对应多个客户端。

具体创建一个.aidl文件,通过AIDL 接口进行通讯。 但是这个 AIDL 接口和普通接口不一样,其内部仅支持六种数据类型:
1、基本数据类型
2、String和CharSequence
3、List 接口(会自动将List接口转为 ArrayList),且集合的每个元素都必须能够被 AIDL 支持
4、Map 接口(会自动将 Map 接口转为 HashMap),且每个元素的 key 和 value 都必须被 AIDL 支持
5、Parcelable 的实现类
6、AIDL 接口本身

binder与socket、管道、共享内存区别

为保护进程不受其他进程破坏和干扰,Linux中的进程都是相对独立的,而起一个进程的内存空间被分为用户空间和内核空间,并且两者也都是相对隔离的

两次拷贝:第一次拷贝是将数据从Aapp的用户空间拷贝到内核缓存区,第二次是从内核空间(包含着内核缓存区)拷贝到Bapp的用户空间
binder的一次拷贝:将数据从Aapp的用户空间拷贝到内核缓存区,内核缓存区与数据接收缓存区存在着映射关系,而数据接收缓存区与Bapp的用户空间存在着映射关系,从而实现传递数据
性能
socket和管道数据拷贝需要两次,binder只拷贝一次,内存共享不需要拷贝,采用映射,但实现起来难度高,复杂性大,安全性也不高。
安全性
传统的通讯方式对于通讯双方并没有做出严格的验证,比如socket和ip需要手动填写,很容易进行伪造。binder机制从协议本身就支持对通讯双方做身份校验,从而提高了安全性。
/***************************************************************************/

二十二、android版本6.0~9.0适配

v6.0:新增9个危险权限组,如果申请的权限属于其中的危险权限时,不仅需要静态注册,还需要动态申请,当用户同意其中一组中的一个权限,那么这个组内的其他权限也会默认同意。
v7.0
1、在7.0之后,不支持在项目中传递file://类型的uri
解决:使用FileProvider进行uri转换成content://类型
2、引入V2签名方式,更加安全,在7.0以下会显示未安装
v8.0(Oreo )
1、通知渠道:可以将自己不感兴趣的通知关掉,相当于分类
方法:先创建通知渠道,再创建通知,传入chnnelId,否则通知将不会显示
2、权限修改:修改了一下6.0的错误,只有当用户使用到已经同意的权限组中的权限时,才会默认同意当前一个权限,而不是刚开始将一组权限都默认立刻同意
3、静态广播无法正常接收:引入了新的广播接收器限制,静态广播将无法使用,只能使用动态广播
4、非全面屏透明页面无法设置方向
5、安装apk权限:需要声明一下添加未知应用的权限:


v9.0(pis):9.0以及以上版本采用androidx包,
1、9.0以后限制了明文流量的网络请求,最好采用https方式请求
在 res 下新建一个 xml 目录,然后创建一个名为:network_security_config.xml 文件 ,该文件内容如下:



    

然后再AndroidManifest,application标签中加入

android:networkSecurityConfig="@xml/network_security_config"

2、刘海屏的适配
v10.0(Q)
1、暗黑模式:Android Q 的暗黑模式和 Android Pie 的暗黑模式不同,在 Android Q 中,暗黑模式适用于任何地方,如果应用不支持暗黑模式,那么系统将自动设置一个暗黑模式。
2、隐私增强
3、超级锁定模式:开启飞行模式关闭所有的传感器
4、限制程序访问剪贴板:新的权限将阻止随机的后台应用程序访问剪贴板内容


5、应用程序降级:当对商店更新后的版本后悔时,可以“回到过去”即回滚到旧版。

二十三、android的多线程几种方式

第一种: HandlerThread
它是在一个线程中,把不同地方的任务,有序的放在消息队列中,Loop()循环取出任务,执行完当前任务才会继续执行下一个任务,HandlerThread就相当于一个线程,同步
第二种: AsyncTask
与第一种一样,但是多了任务执行进度的回调监听,AsyncTask 就相当于是一个线程,同步

class DownloadTask extends AsyncTask//可以传入三个参数,重写方法

第三种: Executors是基于ThreadPoolExecutor的封装

  1. Executors.newFixedThreadPool()
    创建一个定长的线程池,每提交一个任务就创建一个线程,直到达到池的最大长度,这时线程池会保持长度不再变化

  2. Executors.newCachedThreadPool()
    创建一个可缓存的线程池,如果当前线程池的长度超过了处理的需要时,它可以灵活的回收空闲的线程,利用空闲的线程去执行其他任务,不会增加新的线程。当需要增加时,它可以灵活的添加新的线程,而不会对池的长度作任何限制

  3. Executors.newScheduledThreadPool()
    创建一个定长的线程池,而且支持定时的以及周期性的任务执行,类似于Timer

  4. Executors.newSingleThreadExecutor()
    创建一个单线程化的executor,它只创建唯一的worker线程来执行任务

    Executors适用于多任务异步执行

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
		for (int i = 0; i < 30; i++) {
			cachedThreadPool.execute(new Runnable() {
				@Override
				public void run() {
					System.out.println(Thread.currentThread().getName());
				}
			});
		}

第四种: IntentService
IntentService继承自Service,是一个经过包装的轻量级的Service,用来接收并处理通过Intent传递的异步请求。客户端通过调用startService(Intent)启动一个IntentService,利用一个work线程依次处理顺序过来的请求,处理完成后自动结束Service。

适用于后台执行的单个任务

持续更新中…

你可能感兴趣的:(android基础知识汇总,面试,android基础知识汇总)