Android开发艺术探索相关知识点补充--第二章进程间通信补充

1. Android中的ANR是什么,如何分析ANR?-- 原书第35页

较好的相关文章:

https://blog.csdn.net/qq_30993595/article/details/80277333

https://blog.csdn.net/anwanfei/article/details/81140013

https://blog.csdn.net/WHB20081815/article/details/70245594

ANR错误定义(主线程才会导致ANR)

1.用户进行按键操作或者触屏操作时候,应用程序在默认时间范围内(5s)未及时处理,就会出现ANR,其实别说5s了,就是超过1s,用户都觉得不可接受,这种ANR的检测是system_server进程的Inputdispatcher不断检测是否处理完用户的输入事件,一旦超时,就会出现ANR了。

2.主线程在执行broadcastReceiver的onReceiver回调方法在10s内没有处理完事件

3.主线程在执行Service的各个生命周期函数中超过20s没有处理结束

4.大量的线程死循环的去做任务,导致应用获取不到CPU的时间片去处理用户输入事件

ANR错误出现原因:

只有当应用程序的UI线程响应超时才会引起ANR 超时产生的原因包括:

扫描二维码关注公众号,回复: 8589107 查看本文章

①当前事件没有机会处理,例如UI线程正在响应另外的事件,当前事件被某个事件给阻塞掉了;

②当前事件正在处理 但是由于耗时太长没有能及时的完成。其他原因:

③在BroadcastReceiver里做耗时的操作或计算;

④CPU使用过高;

⑤发生了死锁;

⑥耗时操作的动画需要大量的计算工作,可能导致CPU负载过重。

这六种情况其实总结成两个根本原因:

1.主线程做了耗时操作,导致后续用户的输入事件没有及时处理,这是谷歌不可接受的,这样极大的影响用户的体验,只能给开发者抛出来,你得必须给我解决。

2.我们知道应用的事件,不管进程还是线程,最终都是要获取CPU的时间片去处理,假如CPU负载过大,达到100%了,并且还有不断的新事件进入队列,那新事件只能等待了,假如这个新事件是用户的输入事件,那又回到原因1了,但是又有不同,因为这个新的事件可能并不是一个耗时事件;但是在规定的时间内,nputdispatcher检测到这个新事件没有处理完,那也会抛出ANR,让开发者去解决CPU负载问题。

原因如此,那平时开发如何避免呢

1.主线程中不要做任何耗时操作,将这些放到子线程去做

2.开发中注意线程的使用,有没有导致CPU负载过高

ANR错误定位

如果开发机器上出现ANR问题时,系统会生成一个traces.txt的文件放在/data/anr下,最新的ANR信息在最开始部分

如何去分析ANR呢:

各个进程的CPU使用情况; 

CPU负载;

IOWait;

traces文件;

遇到ANR(Application Not Responding)是比较常见的问题。一般情况下,果ANR发生,对应的应用会收到SIGQUIT异常终止信号,dalvik虚拟机就会自动在/data/anr/目录下生成trace.txt文件,这个文件记录了在发生ANR时刻系统各个线程的执行状态,获取这个文件是不需要root权限的,因此首先需要做的就是通过adb pull命令将这个文件导出并等待分析。产生ANR的原因有很多,比如CPU使用过高、事件没有得到及时的响应、死锁等。

辅助处理ANR问题的工具

Traceview - 系统性能分析工具,用于定位应用代码中的耗时操作

Systrace - Android4.1新增的应用性能数据采样和分析工具

2.Android多进程是什么、如何定义、好处、以及可能出现的问题?原书第36页

相关文章:

https://blog.csdn.net/lixpjita39/article/details/77435156

https://blog.csdn.net/goodlixueyong/article/details/49853079

2.1 为何要使用多进程

1.分散内存的占用

我们知道Android系统对每个应用进程的内存占用是有限制的,而且占用内存越大的进程,通常被系统杀死的可能性越大。让一个组件运行在单独的进程中,可以减少主进程所占用的内存,避免OOM问题,降低被系统杀死的概率,

2.实现多模块

比如我做的应用大而全,里面肯定会有很多模块,假如有地图模块、大图浏览、自定义WebView等等(这些都是吃内存大户),还会有一些诸如下载服务,监控服务等等,一个成熟的应用一定是多模块化的。

3.子进程奔溃,主进程可以继续工作

如果子进程因为某种原因崩溃了,不会直接导致主程序的崩溃,可以降低我们程序的崩溃率。 
4.主进程退出,子进程可以继续工作

即使主进程退出了,我们的子进程仍然可以继续工作,假设子进程是推送服务,在主进程退出的情况下,仍然能够保证用户可以收到推送消息。 


5.实现守护进程

2.2 多进程的创建

process分私有进程和全局进程:

私有进程的名称前面有冒号:android:process=":musicservice"

全局进程的名称前面没有冒号:android:process="com.trampcr.musicdemo.service"

2.3 使用多进程带来的麻烦

1)Application的多次重建。

2)静态成员和单例模式的完全失效。

3)文件共享问题。--Sharedpreference的可靠性下降

4)断点调试问题等

3.序列化与反序列化--原书第42页

1、序列化是干什么的?

简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保存object states,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。

2、什么情况下需要序列化

a)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候; 
b)当你想用套接字在网络上传送对象的时候; 
c)当你想通过RMI传输对象的时候;

3、Parcelable和Serializable的区别:

内存间数据传输时推荐使用Parcelable,如activity间传输数据

保存到本地或者网络传输时推荐使用Serializable
 

4.binder相关--原书第47页

参考博客:Android AIDL跨进程通信

https://blog.csdn.net/cpcpcp123/article/details/90208023

这个讲解IPC例子很好的一个文章:https://github.com/leavesC/IPCSamples

发布了189 篇原创文章 · 获赞 81 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/cpcpcp123/article/details/96709125