自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(15)
  • 收藏
  • 关注

原创 深入理解WMS

一个WindowToken就代表一个应用组件,应用组件包括Activity,InputMethod等。先有个模糊的过程:用户定义的layout在启动activity时通过setContentView加载,此过程会把xml布局“翻译”成具体的view,客户端通知WMS添加此view,WMS构建个此“窗口”,这里有可能有多个应用同时显示,比如状态栏,导航栏,所以wms可能同时构建几个要显示的“窗口”,就需要把这几个窗口做个合并,哪个窗口再哪里显示,拼接出来的数据再通知SurfaceFlinger去显示。

2024-08-26 23:25:25 531

原创 深入理解Watchdog

Watchdog实现原理很简单:开机后先获取单例,在构造函数中把监听的线程的handler封装起来,要监听的系统服务单独封装到fg线程,后面通过addMonitor和addThread加入到相应的队列,再调用start方法异步线程,异步线程启动本地run方法,run方法中先遍历要监听的列表,分别计算出开始时间,然后等待30s再评估出最差的状态,如果超过30s就先dump一次日志,超过1分钟就写进dropbox日志,再杀掉当前进程即systemserver进程,即系统会重启。

2024-08-26 23:24:54 1057

原创 深入理解SurfaceFlinger

Handle其实就是个binder对象,相当于SurfaceFlinger把此对象的代理对象返回给SurfaceComposerClient的进程,即wms所在的进程-system_server进程,再在注释27处基于此binder对象来创建SurfaceControl对象,再把SurfaceControl对象的内存地址传给wms进程的java端,再返回给客户端,客户端就可以基于此地址来操作SurfaceControl,即变相操作SurfaceFlinger的layer完成合成等操作。

2024-08-26 23:24:15 1388

原创 BroadcastReceiver广播注册和发送流程

广播的发送通过AMS先从mReceiverResolver缓存查询指定BroadcastFilter,封装成BroadcastRecord然后入队等待队列一个个执行,如果还有老的同样的广播没执行完,就不添加新的广播。如果进程不存在,就直接回调。这里可以看到广播的发送不是立即就会被接受者接收的,而是放到了调度队列,并通过handler发送消息给接受者。+ 由于发送的时候广播是按队列执行,所以广播的发送不是立即就被接收者接收,也可能发送了3个同样的广播,由于队列执行较慢,只接收一个广播的情况。

2024-08-26 23:23:28 831

原创 关机流程详解

这里不止点电源键是这样的流程,所有的key事件,比如点home,back,或者手动触发的keycode事件,都会走这个流程。3. jni层会监听这个属性的改变,一旦改变会调用PropertyChanged方法,最终调用DoReboot去关机,这里会把所有的服务关闭,卸载挂载的设备,比如sd卡等,最后调用RebootSystem到kernel层去真正关机。syscore作为低功耗流程的一部分,其涉及的文件主要有syscore_ops.h和syscore.c,这一级别的回调函数是在完全屏蔽中断的场景下进行的。

2024-08-26 23:22:35 561

原创 开机流程详解

比如由zygote进程执行fork操作fork出system_server进程时,新fork出的system_server进程也会继续执行,所以关键点一中zygote进程和system_server进程都会返回,只不过父进程(zygote进程)返回Runable的是空,子进程返回的非空。然后0号进程fork出1号init进程(用户进程,所有用户进程的祖先),2号kthredd进程(内核进程,是所有linux进程的祖先),还会初始化Camear,Display,input,binder驱动。

2024-08-26 23:21:42 315

原创 深入理解共享内存

Binder驱动通过当前进程的fd找到对应的文件,然后为目标进程创建新的fd,并传递给目标进程,来看下Android中binder的实现(以下代码非android13)注释1上面的英文注释写的很清楚,此方法会根据传过来的FileDescriptor创建个新的重复的FileDescriptor,这两个FileDescriptor共享同样的文件状态,即指向的是同一个文件,后面再通过binder通信把新创建的FileDescriptor的包装类ParcelFileDescriptor传到其他进程。

2024-08-26 23:20:44 1300

原创 Service启动流程

注释写的很清楚,注释1先去判断对应的service是否已经创建,如果创建了,直接走sendServiceArgsLocked流程。否则走注释2,先看对应服务的进程是否启动,即ProcessRecord,如果进程启动了就直接通过realStartServiceLocked去启动服务,如果进程没启动,就通过注释4调用AMS.startProcessLocked来启动对应进程,然后把要启动的服务先缓存到mPendingServices中,待要启动进程启动好后再拉起服务。至此,bindService也介绍完了。

2024-08-26 23:19:54 719

原创 深入理解pms

可以看到从以下目录获取permissions,(空,vendor,oem,odm,product,system)/etc/(permissions,sysconfig)这12个文件夹下的所有xml,另外还从(system,system_ext,product)/ect这3个目录读以public.libraries-开头,.txt结尾的NativeLibraries文件。PMS是android系统很重要的一个系统服务,主要负责管理应用的安装,卸载,更新,查询,权限管理。代码基于Android13。

2024-08-26 23:19:19 559

原创 LeakCanary实现原理

2 在监听对象的销毁方法中,先把对象加入到观察者对象列表中,利用WeakReference和ReferenceQueue的特性,5s后判断ReferenceQueue中是否能poll出相应的WeakReference来判断对象是否泄露,能poll出说明被销毁,从观察者列表中移除此对象,不能poll出说明还没被销毁,把其加入到怀疑列表。基于以上原理,把需要观察的对象(Activity,fragment)等加到弱引用容器中,并指定ReferenceQueue,一段时间后从queue里判断是否能拿到弱引用。

2024-08-26 23:18:18 925

原创 JNI相关

新建个c++项目`cjnitest`,修改下默认的MainActivity,新加个与jni通信的方法`getStringPwd`和静态方法`getStaticPwd`,传递java层的name过去,jni处理后返回响应的String。//采用c的方式,禁止函数重载(即c++是允许同名的函数,c不允许同名函数,为了解决同名问题,jni默认采用c的方式)//java层定义的静态方法与非静态的区别是传过来的是jclass,即是类,而非静态传过来的是jobject,即是对象。

2024-08-26 23:17:35 251

原创 installd守护进程

在[PMS启动流程](https://github.com/beyond667/study/blob/master/note/PMS%E5%90%AF%E5%8A%A8%E6%B5%81%E7%A8%8B.md)安装流程的最后一步commit时调用executePostCommitSteps,最终会执行到Installer.dexopt来通过JNI层去真正安装,PMS只是对apk做了拷贝和解析,真正干活的是在installd守护进程。art虚拟机生成的是oat,jvm虚拟机生成的是odex文件。

2024-08-26 23:16:34 694

原创 HashMap & ArrayMap & SparseArray

数据结构|1.8之前是数组+单链表,1,8之后再加红黑树(链表长度大于8变树,树长度减少到6时变回单链表)|两个数组,一个数组存key的hash值(从小到大排序),一个存key和value|两个数组,一个存key(从小到大排序),一个存value|+ 到注释7 8会真正插入进去,如果index不在队尾,先把index处以后的数据都往后移一位,再在mHashes数组的index处插入key的hash值,mArray的2 * index处插入key,2*index+1处插入value。

2024-08-26 23:15:58 820

原创 深入理解ContentProvider

这里拿到服务端传来的共享内存的fd,其实这里跟服务端的fd并不是同一个对象,而是其拷贝,这两个fd指向的是同一个文件描述,后面客户端对此共享内存的数据就可以做操作了。关于共享内存的原理可以参照[共享内存](https://github.com/beyond667/study/blob/master/note/%E5%85%B1%E4%BA%AB%E5%86%85%E5%AD%98.md) ,这里关注ContentProvider在数据传输时是怎么共享内存的。(本文基于Android13)

2024-08-26 23:15:25 854

原创 Activity启动流程

要更新UI,比如更新TextView,Button(继承TextView),都会调用View.requestLayout,然后一直调用父view的requestLayout,直到DecorView,DecorView的parent是ViewRootImpl,即最终调用到ViewRootImpl.requestLayout。到主线程的hander。注意的是执行完Activity.onResume后Activity并没有可见,这时候view还没绘制,真正可见需要执行activity.makeVisible。

2024-08-26 23:14:18 523

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除