最近也去面试了几家公司,现在这个物联网行业这个行情也不是特别的好,也是有点下坡路的感觉。但是工作还是要找的嘛,毕竟我们也是靠这个来吃饭,我们可以在完成工作的同时提高自己,完善自己。希望大家在这个面试旺季都可以找到一个适合自己的工作!接下来步入正题:
问题:
1.App启动流程
2.栈和堆
3.apk瘦身
4.Android的四种引用的使用
解决:
1.APP启动流程
这个也是最近面试特别常问到的,对于初级程序员来说:不就是说生命周期嘛,简单。对于初级程序员以上来说:这个东西又问到底层了,好烦啊!从每个阶段来看的角度都是不一样的,接来下我给大家整理一下最近我初步了解的APP的启动流程的步骤:
①点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求;
②system_server进程接收到请求后,向zygote进程发送创建进程的请求;
③Zygote进程fork出新的子进程,即App进程;
④App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;
⑤system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求;
⑥App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;
⑦主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法。
⑧到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染结束后便可以看到App的主界面。
2.栈和堆
这个问题最近我也是在面试中问到,当时回答的也是很模糊,没有说对底层有特别的了解,在总结的时候我们肯定是要重新了解一下这个栈和堆的关系的,废话少说,上图:
JVM虚拟机
堆:
垃圾回收的主要内存,用来存放实例化的对象以及数组等。
JVM堆内存分为2块: Permanent Space和Heap Space。
又分为三代:
年轻代:包括一个eden和两个survior,往往使用复制垃圾回收算法(Young GC)进行回收。
年老代:存放生命周期比较长的数据(通过反射产生的class对象),年老代采用标记-清除Gc算法跟标记-整理GC算法(FULL GC)。
永久代:用来存放静态变量以及通过java反射产生的class对象。
jvm栈:
java方法运行时分配的内存,jvm栈会为每个即将运行的java方法分配一个叫帧栈的区域,用来存储方法运行时所需的信息,信息主要包括局部变量表,操作数栈,动态链接以及方法出口信息,线程私有的,生命周期随着线程的创建而创建,随着线程的销毁。
本地方法栈:
功能与jvm栈类型,只不过是java本地方法(native关键字修饰的方法,通常比较底层,用于链接操作系统与java)时分配的内存模型。
3.apk瘦身
so文件的优化:
通常我们在使用NDK开发的时候,我们经常会有如下这么一段代码:
ndk {
//设置支持的so库架构
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64", "armeabi"
}
最后我的修改代码如下:
ndk {
//设置支持的so库架构
abiFilters "armeabi-v7a"
}
接下来说明这么做的依据:
看上面图分析,armeabi-v7主要不支持ARMv5(1998年诞生)和ARMv6(2001年诞生).目前这两款处理器的手机设备基本不在我公司的适配范围(市场占比太少)。
而许多基于 x86 的设备也可运行 armeabi-v7a 和 armeabi NDK 二进制文件。对于这些设备,主要 ABI 将是 x86,辅助 ABI 是 armeabi-v7a。
最后总结一点:如果适配版本高于4.1版本,可以直接像我上面这样写,当然,如果armeabi-v7a不是设备主要ABI,那么会在性能上造成一定的影响。
优化res,assets文件大小
手动lint检查,手动删除无用资源
在Android Studio中打开“Analyze” 然后选择”Inspect Code…”,范围选择整个项目,然后点击”OK”。
使用tinypng等图片压缩工具对图片进行压缩。
打开网址,将大图片导入到tinypng,替换之前的图片资源。
大部分图片使用Webp格式代替。
可以给UI提要求,让他们将图片资源设置为Webp格式,这样的话图片资源会小很多。如果想了解更多关于webp,请点击这里webp,当然,如果对图片颜色通道要求不高,可以考虑转jpg,最好用webp,因为效果更佳。
尽量不要在项目中使用帧动画
一个帧动画几十张图片,再怎么压缩都还是占很大内存比重的。所以建议是让UI去搞,这里可以参考使用lottie-android,如果项目中动画效果多的话效果更加明显。当然这就要辛苦我们UI设计师大大了。
. 使用gradle开启shrinkResources
移除无用资源文件,下面是我的配置:
release {
// 不显示Log
buildConfigField "boolean", "LOG_DEBUG", "false"
//混淆
minifyEnabled true
// 移除无用的resource文件
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
通过上述步骤操作,又优化了将近5M,别问我为什么还有7.5M,里面大量的gif和webp格式的动图,都是UI丢给我的,一个2.7M.后面再慢慢和他细究这个问题。后面要做的两部分,一部分是将资源文件下的所有gif图放后台下载处理,第二个是和UI讨论下如何减小webp 动图的大小(我看其他平台只有100K的样子,给我的就2.7M)。
5. 其他
1.删除无用的语7zip代替
2.删除翻译资源,只保留中英文
3.尝试将andorid support库彻底踢出你的项目。
4.尝试使用动态加载so库文件,插件化开发。
5.将大资源文件放到服务端,启动后自动下载使用。
线上项目的版本更新
大家可以看一下这篇特别好的文章:
Android 版本更新迭代
Android的四种引用的使用
1.强引用
平时我们编程的时候例如:0 bject ob ject=new0 bject():那 objects就是
个强引用了。如果一个对象具有强引用,那就类似于必不可少的生活用品,垃圾
回收器绝不会回收它,当内存空间不足,Jawa虚机宁抛出
Out Of memoryerror错误,使程序异常终止,也不会辞随意回收具有强引用的对象
来解决内存不足问题
//创建一个强引用
String str new Str ing(“hello”)
2.软引用( Softreference)
如果一个对象只具有软引用,就类似于可有可物的生活用品.如果内存空间足
不足了,就会回收这些时的内
该对象就可以被程序使用、软引用可用来实现内存敏
口个引用队列( Referencequeue)联合使用,如果软
用所引用的对象被垃圾回收,ava拟机就会把这个软引用加入到与之关联的引
用队列中
//创建一个强引用
String str= new String(“hello”)
//创建引用队列:为范型标记,表明队列中存放 String对象的引用
个弱引用,它引用" hello’对象,井且与rq引用队列关联
标记,表明 Weakreference会弱引用 Str ing对象
erence: wf =new Weakreference(str, ra)
3.弱引用( Weak Reference)
如果一个对象只具有弱引用,类似于可有可物的生活用品。弱引用与软引用的区别
只具有弱引用的对象拥有更短的生命周期。在垃圾回收器线程扫描它所管辖的内
存区域的过程中,一旦发現了只具有弱引用的对象,不管当前内存空间足够与否,都会回
收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那
些只具有弱引用的对象。弱引用可以和个引用队列( Referencequeue)联合使用,如
果弱引用所引用的对象被垃圾回收,ava虚拟机就会把这个弱引用加入到与之关联的引用队列中
4.虚引用( Phantomreference)
虚引用顾名思义,就是形同虚设,与建他几种引用都不同,虚引用井不会决定对象的
生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任问时候都可
能被垃圾回收。虚引用主要用来跟踪对象被垃圾回收的活动。虚引用与软引用和弱引用的
一个区别別在于:虚引用必须和引用队列( Referencequeue)联合使用,当垃圾回收器准
回收一个对象时,如果发现它还有成引用,就会在回收对象的内存之前,把这个虚引用加
入到与之关联的引用队列中,程序可以通过判断引用队列中是否已经加入了虚
解被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经械加入到引用队列
么就可以在所引用的对象的内存被回收之前来取必要的行动
网友评论