Android系统本身其实并不差,它经过几代系统的优化已经很流畅了,只不过因为一些原因导致它的表现比IOS差很多。也就是说只是被一些Android设备产商搞坏了口碑。
下面我将列举它性能差的两个主因:
一、厂商
1.系统定制过度
某些产商会在Android系统的基础上内置很多自家开发的App全家桶,例如广告推送、自家主题、应用分身等,这些App会增加CPU、内存的占用,尤其在低端机更明显。
2.低端硬件市场策略
Android产商为了覆盖低端市场,会使用低频的CPU、低速闪存和少量的RAM,这就导致了平时大家见到的Android手机性能差的原因。
而苹果做工精细,产品要求度高,各方面硬件都要求达到尖端,所以这也是IOS性能好的一个原因。
3.优化不足
Android手机用久了电池老化频率下降,产商会做省电策略导致流畅度下降,并且存储了大量系统应用、临时文件、日志、图片缓存等,再加上内存管理不善碎片化,导致系统越用越卡。
不同厂商的底层驱动实现复杂度高,系统无法像 iOS 那样统一调度,导致在相同的配置下,IOS的性能比Android好。
Android和IOS的差距其实不大,只是产商的处理放大了他们之间的差距。不过有些Android产商经过深度优化,性能很接近苹果旗舰机,甚至在某些方法已经超过苹果。
例如三星的Samsung Galaxy S25 Ultra,它代表着Android阵营的顶级旗舰机,性能跑分、GPU 图形、某项实测中已经超过苹果旗舰机。
二、APP开发不当
就算Android再好,如果开发不当,也容易造成系统性能差的问题。其实Android开发比其他软件容易造成性能问题,因为下面这两个问题:
1.在主线程做耗时操作
2.内存管理不善
Android应用开发最理想的境界是:
除了view.setvalue更新数据外,其他代码都应该不要放在主线程执行,也就是说放在子线程运行,但我们开发者喜欢在主线程做处理,所以就造成APP不流畅。
线程调度方面可以按这种方式处理:Java可以用RxJava优化,kotlin可以用协程优化
下面将举一下常见的场景:
(1)RecyclerView点击导致UI卡顿
在itemListener里面做耗时操作
@Overridepublic void onBindViewHolder(MyViewHolder holder, int position) {String item = dataList.get(position);holder.textView.setText(item);holder.itemView.setOnClickListener(v -> {// 执行耗时操作User user = userdao.getUser();Bitmap image = HttpUtils.getBitmap(Url);}例如上面的操作,在点击事件里面做耗时操作,itemListener实际上也是在主线程,在主线程中做耗时操作是会阻塞UI的,所以itemListener里面的要用子线程处理耗时操作。
(2) 在LiveData里做业务处理
我发现有些项目喜欢通过LiveData进行通信,也就是说在LiveData消费者里面做处理,例如:
userViewModel?._user?.observe(this) {//1.进行网络请求//2.进行dao数据获取}这个是一个很隐蔽的问题,可能很多人不知道observe(this){} 是运行在主线程的,在里面做程序处理,很容易让应用卡顿。
.observe(this){textView.text = it}LiveData只能用来更新UI,如果想通信的话,可以使用kotlin的Flow流来进行通信,或者RxJava。
(3) 在主线程调用AIDL
aidl是进程间通信的一种方式,所以他们是一种耗时操作,很多人可能认为它需要在主线程运行,其实不是,最理想的做法是用子线程调用,防止它阻塞主线程。例如在主线程调用:
openDeviceBtn.setOnClickListener{myDeviceAIDL.openDevice(params);}(4) 在主线程做与UI无关逻辑
我发现很多APP,喜欢在主线程做一些与UI更新无关的事件,例如json字符串解析、数据遍历、工具类初始化、日志保存等,这些操作其实都不需要放主线程执行的。
也就是说我们在子线程处理完数据,得到最后的结果后再通过主线程setView。比如:
override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)HttpUtil.init();LogUtil.init();SDK.init();//第三方sdk等MQUtil.init();//解析操作val json = "{\"name\":\"zgr\"...}"val obj = Gson**.parse(jsong)itemListenr{for(1...1000){//遍历new Object()这种问题也不能全怪开发者,这种事情最好从根源去解决问题,Android系统就不应该把主线程开放出来,而是提供非主线程的回调,并且只提供更新UI的接口。
(5)内存管理问题
最严重的问题就是内存泄漏,其次是内存碎片化,第一个还有途径解决,第二个就比较隐蔽了。
在Android中该缓存的就需要缓存,特别是一些大数据对象,例如Bitmap。这类对象new出来后,是直接进入JVM的老年区的,就算没有引用它了,普通的gc也清理不了它。只能等内存满了进行了full gc了才能清理。
或者手动销毁Bitmap,但是频繁和销毁也容易造成内存碎片化,也同样造成内存紧张。我们都知道内存连续化的,如果碎片化就容易造成下面的问题。
1
2
3
4
5
数据1
空闲
数据2
空闲
数据3
假设有个数据要存储时,大小都不符合2和4,它就保存不了,除非2和4相连并且大小合适才能存储进入。
这就是为什么有时候看到明明还有内存,但是还是显示内存空间不足。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.