源码介绍 线程运行流程 先看下RecordThread的创建: AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger 20 ms each; this ensures we can sleep for 20ms in RecordThread size_t pipeFramesP2 = roundup(4 onFirstRef void AudioFlinger::RecordThread::onFirstRef() { run(mThreadName, PRIORITY_URGENT_AUDIO); } 对于Android front = android_atomic_acquire_load(&cblk->u.mStreaming.mFront); rear = cblk->u.mStreaming.mRear rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear); front = cblk->u.mStreaming.mFront
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
(队列里消息是通过Handler发送的) BEDAA5C0-9057-4ADA-B202-FF7540C34DF0.png 接下来我们就逐步学习他吧。 二、源码解析 Looper源码解析 Android应用程序进程在启动的时候,会在线程中加载 /frameworks/base/core/java/android/app/ActivityThread.java next源码 Message next() { final long ptr = mPtr; ............... Looper大致就这些,下面看下Handler Handler源码解析 无限循环遍历MessageQueue过程就这些,上面讲了如何获取Message以及MessageQueue如何阻塞的。 dispatchMessage源码 public void dispatchMessage(@NonNull Message msg) { if (msg.callback !
在SqlSession接口中包含了所有可能执行的sql语句在这里不一一列举,请参考org.apache.ibatis.session.SqlSession源码。 1 //org.apache.ibatis.session.defaults.DefaultSqlSession 2 …… 3 @Override 4 public <E> List<E> private <E> Object executeForMany(SqlSession sqlSession, Object[] args) { 3 List<E> result; 4 1 //org.apache.ibatis.binding.MapperMethod 2 public static class SqlCommand { 3 4 private final 37 38 public SqlCommandType getType() { 39 return type; 40 } 41 } 大致对MapperMethod的解读到此
一.Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity;
(最短栈、最长栈) private[spark] case class CallSite(shortForm: String, longForm: String) 源码中通过「getCallSite( )」 方法配置返回CallSite 参数示意: 参数英文名 参数含义 lastSparkMethod 方法存入 firstUserFile 类名存入 firstUserLine 行号存入 源码如下:
metricsSystem, memoryManager, outputCommitCoordinator, conf) 总结 Spark Env 源码顺序大致就是上面的流程 ,更细致的后面的博文中会持续更新解读。
. //4.
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
处理消息 整体的流程有了,但是一直没有结合源码捋一捋。 这才去翻了翻源码,今天总结一下。 Android 消息机制主要涉及 4 个类: Message MessageQueue Handler Looper 我们依次结合源码分析一下。 /os/message.html#62dadbbac34056e7ad4fad36d757d6ef 可以看到,这个方法会获取前面提到的 private static Message sPool; ,如果 这篇文章暂不研究 Native 层源码。 这篇文章结合源码完整的看了一遍 Message MessageQueue Handler Looper,现在看着上面的图,可以自信地说我“熟悉 Android 消息机制”了哈哈。
源码结构目录 可以看到此模块定义了4个属性和12个函数,我们依次来讲解 属性源码分析 # 匹配http://或https:// absolute_http_url_regexp = re.compile \-/\s=,]*)\)\}") 函数源码分析 parse_string_value 作用:将字符串转换为数字 "123" => 123 "12.2" => 12.3 "abc" => "abc" "$ parse_function_params("a=1, b=2") {'args': [], 'kwargs': {'a': 1, 'b': 2}} >>> parse_function_params("1, 2, a=3, b=4" ) {'args': [1, 2], 'kwargs': {'a':3, 'b':4}} get_mapping_variable 作用:获取映射变量 get_mapping_function 作用 add_one": lambda x: x + 1} >>> parse_string(raw_string, variables_mapping, functions_mapping) "abc4def
NETD 一、NETD解读 1.1、NETD的作用 Netd是Android系统中专门负责网络管理和控制的后台daemon程序,其功能主要分三大块: 设置防火墙(Firewall)、网络地址转换(NAT Android系统中DNS信息的缓存和管理。 Netd位于Framework层和Kernel层之间,它是Android系统中网络相关消息和命令转发及处理的中枢模块。 strcmp(argv[2],"enable")); return sendGenericOkFail(cli, res); } 二、iptable解读 2.1、iptable原理 createChildChains(V4V6, "filter", "OUTPUT", FILTER_OUTPUT); createChildChains(V4V6, "raw", "
你能通过源码看见 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执行完毕后,再执行后面的代码。 else { //优先尝试监听本地icmp,批量探测 conn, err := icmp.ListenPacket("ip4:icmp", "0.0.0.0") if err = //尝试无监听icmp探测 fmt.Println("trying RunIcmp2") conn, err := net.DialTimeout("ip4:
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 (p.casNext(null, newNode)) { // 4. if (p ! q : p); return item; } // 4.
看下源码,我们发现在cancelAll、finish方法中使用。 4.如果缓存内容有问题,清空当前缓存内容同时添加网络请求队列,结束。 4.如果缓存不需要更新,则数据回调给使用者,结束。 4.标记当前请求成功同时把数据回调给使用者。 2.策略模式 当Android SDK小于9时,基于HttpClient创建HttpStack,否则基于HttpURLConnection创建HttpStack,还可以自定义Stack 3.模板方法模式 从源码中我们可以得知,网络请求线程只有4个,缓存请求线程只有1个,如果请求大数据,那就导致线程在一定的时间内被占用,5个线程很容易被用完,再有请求时回导致堵塞,UI体验较差。
源码阅读 核心功能在store.js,根据注释阅读便于理解。 总结 最后我们回过来看文章开始提出的5个问题。 引用 Vuex框架原理与源码分析 -美团 Examples Counter Counter with Hot Reload TodoMVC Flux Chat Shopping Cart Running
TaskSceduler在具体创建的时候,是由不同发布模式比如standalone、yarn、mesos决定的,返回一个SchedulerBackend.