源码介绍 public AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, iMemPointer; audio_track_cblk_t* cblk; status_t status; static const int32_t kMaxCreateAttempts = 3; (mTransfer == TRANSFER_SYNC) || // use case 3: obtain/release mode (mTransfer // return handle to client recordHandle = new RecordHandle(recordTrack); // 包装成binder, 证明了猜想3 a whole notification period (minNotificationsByMs) static const size_t kMinNotifications = 3;
34B66A6E-F3C7-4D02-A508-14F271CD3445.png A6A6A7B1-1CC9-4820-9F87-D513CA85F93C.png 48C9C055-75B4-4B0B -9D82-8F8A699AA1C1.png 449E97DB-A71E-4E1E-8915-7E9A6BFFE07D.png D397C456-AD94-42DB-8123-74FB3CF44FAB.png
二、源码解析 Looper源码解析 Android应用程序进程在启动的时候,会在线程中加载 /frameworks/base/core/java/android/app/ActivityThread.java next源码 Message next() { final long ptr = mPtr; ............... invariant: p == prev.next prev.next = msg; } //-------------------------3- 代码3,每次插入msg的时候,判断needWake,是否要唤醒当前线程,上面代码我们知道,当消息插入对头的时候,如果当前线程处于睡眠状态,needWake=true。 dispatchMessage源码 public void dispatchMessage(@NonNull Message msg) { if (msg.callback !
在前面两篇的MyBatis源码解读中,我们一路跟踪到了MapperProxy,知道了尽管是使用了动态代理技术使得我们能直接使用接口方法。为巩固加深动态代理,我们不妨再来回忆一遍何为动态代理。 1 package day_16_proxy; 2 3 /** 4 * @author 余林丰 5 * 6 * 2016年11月16日 7 */ 8 public interface 回到我们的MyBatis源码,在上一节中我们知道了一个Dao接口实际上是通过MapperProxyFactory生成了一个MapperProxy代理类。 (注意:在阅读这部分源代码时,我们的主线是MyBatis是如何创建出一个代理类,以及实现其方法的,而暂时忽略其中的细节) 我们选择常见的"SELECT"sql语句来进行解读,而在"SELECT"语句中又会设计到较多的细节问题 sqlSession.selectOne(command.getName(), param); 15 } 16 break; 我们选取第7行中的executeForMany中的方法来解读试试看
一.Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity;
(最短栈、最长栈) private[spark] case class CallSite(shortForm: String, longForm: String) 源码中通过「getCallSite( )」 方法配置返回CallSite 参数示意: 参数英文名 参数含义 lastSparkMethod 方法存入 firstUserFile 类名存入 firstUserLine 行号存入 源码如下:
关联ActiveJob中的调度池,作业组,描述等 val properties = jobIdToActiveJob(jobId).properties //3.
metricsSystem, memoryManager, outputCommitCoordinator, conf) 总结 Spark Env 源码顺序大致就是上面的流程 ,更细致的后面的博文中会持续更新解读。
1.直接看下setContentVIew源码 activity.java public void setContentView(@LayoutRes int layoutResID) { getWindow ().setContentView(layoutResID);// initWindowDecorActionBar(); } 1.在activity.java源码中我们可以看到 mWindow = new PhoneWindow(this, window, activityConfigCallback);所以我们直接看PhoneWindow源码中的setContentView。
前言 对于Android开发者来说,View无疑是开发中经常接触的,包括它的事件分发机制、测量、布局、绘制流程等,如果要自定义一个View,那么应该对以上流程有所了解、研究。 以下源码均取自Android API 21。 Activity中,会在onCreate()方法中写下这样一句: setContentView(R.layout.main); 显然,这是为activity设置一个我们定义好的main.xml布局,我们跟踪一下源码 尝试追踪一下源码,发现mWindow是Window类型的,但是它是一个抽象类,setContentView也是抽象方法,所以我们要找到Window类的实现类才行。 mContentRoot = (ViewGroup) in; ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT
/hello.js"></script></body></html>Vue3源码视频讲解:进入学习源码解读关于Vue3中数据发生变更,最终影响到页面发生变化的过程,我们本篇文章只对componentEffect null;parentComponent为instance实例;parentSuspense为null;isSVG为false;optimized为false;来看下processFragment函数的源码 ul结尾生成的对象;parentComponent:instance实例;parentSuspense:nullisSVG:false;optimized:true;下面看下patchChildren的源码 ;parentComponent:instance实例;parentSuspense:nullisSVG:false;optimized:true;接下来看下patchKeyedChildren函数的源码 为1,l2为4,e1为3,e2为3;第一次循环,old-d与new-b是不相同的,break;跳出循环,从尾部开始的循环结束;进入第一个if判断为false,进入第二个else-if判断为false,进入
注:上面我们模拟的 useState 并没有做这个处理 后面我会讲解源码中去解析。 Hooks 源码解析该源码位置: react/packages/react-reconciler/src/ReactFiberHooks.jsconst Dispatcher={ useReducer (轻量级 3kb)注意:这里的替代是指如果不用 react 的话,可以使用这个。而不是取代。 useState 源码解析调用了 useReducer 源码export function useState(initialState) { return useReducer(invokeOrReturn 大概了解了点重要的源码,做到知其然也知其所以然,那么在实际工作中使用他可以减少不必要的 bug,提高效率。
处理消息 整体的流程有了,但是一直没有结合源码捋一捋。 这才去翻了翻源码,今天总结一下。 Android 消息机制主要涉及 4 个类: Message MessageQueue Handler Looper 我们依次结合源码分析一下。 /os/message.html#50de1a696587dcd5ae3c91eb63985af2 的确就是在 obtainI() 的基础上加了一些赋值。 这篇文章暂不研究 Native 层源码。 这篇文章结合源码完整的看了一遍 Message MessageQueue Handler Looper,现在看着上面的图,可以自信地说我“熟悉 Android 消息机制”了哈哈。
---- Pre Spring5源码 - 04 invokeBeanFactoryPostProcessors 源码解读_1 Spring5源码 - 05 invokeBeanFactoryPostProcessors 源码解读_2 ---- 细说invokeBeanDefinitionRegistryPostProcessors 前两篇博文 我们过了一下这个方法的主干流程,其中有个关键的方法,我们没有细说就是这个invokeBeanDefinitionRegistryPostProcessors 话不多说,还是下来梳理主干流程,然后再对着源码过一遍 ---- 流程图 我们来看流程图 ? /2:获取告诉子类初始化Bean工厂 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //3: 重点关注 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); 这个方法就是我们今天要研究的源码
ButterKnife是一个专注于Android系统的View注入框架,有了ButterKnife可以很轻松的省去findViewById,ButterKnife用到的注解并不是在运行时反射的,而是在编译的时候生成新的 class,对运行时性能没有影响,本篇我们来详细学习一下它的源码。 view.setTag(holder); } holder.name.setText("Donkor"); holder.job.setText("Android 指定多个id绑定事件: public class MainActivity extends AppCompatActivity { //Tip:当涉及绑定多个id事件时,我们可以使用Android 如果有标记@OnClick注解,则对view进行点击事件设置 到这里,ButterKnife的源码分析流程基本结束,如有不对的地方,可以指出校正。
NETD 一、NETD解读 1.1、NETD的作用 Netd是Android系统中专门负责网络管理和控制的后台daemon程序,其功能主要分三大块: 设置防火墙(Firewall)、网络地址转换(NAT Android系统中DNS信息的缓存和管理。 Netd位于Framework层和Kernel层之间,它是Android系统中网络相关消息和命令转发及处理的中枢模块。 setenv("ANDROID_DNS_MODE", "local", 1); //创建DnsProxyListener,它将创建名为"dnsproxyd"的监听socket dpl = strcmp(argv[2],"enable")); return sendGenericOkFail(cli, res); } 二、iptable解读 2.1、iptable原理
你能通过源码看见 Row 和 Column 都继承了 Flex ,布局具体的计算都在这个类中,我们可以通过源码 github.com/flutter/flut 了解一下 Flex 是如何计算布局的。 const <Widget>[], }) 基本上默认值的设计不管是 Row 还是 Column 都遵循了 Flex 的设计,唯一相比之下只有 this.direction 参数是多余出来的一个,通过源码的注释我们可以了解到它是用于设置轴的排列方向
Hosts)) } if common.Scantype == "icmp" { common.LogWG.Wait() return } common.GC() CheckLive函数(源码解读在 其它情况则调用PortScan函数(源码解读在portscan.go中)扫描存活的端口。LogWG.Wait()会等待PortScan函数中的goroutine执行完毕后,再执行后面的代码。 fmt.Println("trying RunIcmp2") conn, err := net.DialTimeout("ip4:icmp", "127.0.0.1", 3*
3: CountDownLatch: 用state变量作为计数器,在初始化时指定。 AbstractQueuedSynchronizer关键属性 下面来看看acquire获取锁的部分源码: public abstract class AbstractQueuedSynchronizer 源码如下: abstract static class Sync extends AbstractQueuedSynchronizer { //非公平锁最终最调用到当前这个方法,传入的acquires 源码如下: //这个方法是不允许子类重写的 final boolean acquireQueued(final Node node, int arg) { boolean failed 下面再来看看释放锁的逻辑AbstractQueuedSynchronizer的relase源码如下: //释放锁需要调用release方法 public final boolean release
二、源码解读 现在我们有了 head 和 tail 节点,如果按照我们平常的思维,head 节点即头节点,tail 节点即尾节点。 想要读懂 ConcurrentLinkedQueue 的源码,最好先搞懂以下特质: 队列中任意时刻只有最后一个元素的 next 为 null head 和 tail 不会是 null(哨兵节点的设计) if (q == null) { // 3. = null && p.casItem(item, null)) { // 3. if (p ! 同第3点解释类似,如果 p.next == null,表明已经是最后一个节点了,则只能更新 head 为 p 节点,返回 null。 什么情况下会出现 p == q 呢?即 p == p.next 。