<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Posts on midFang&#39;s Blog</title>
    <link>https://midFang.github.io/post/</link>
    <description>Recent content in Posts on midFang&#39;s Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Fri, 17 Apr 2026 00:00:00 +0000</lastBuildDate>
    
	<atom:link href="https://midFang.github.io/post/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>《财富自由之路》读书笔记</title>
      <link>https://midFang.github.io/books-wealth-freedom-road-reading-notes/</link>
      <pubDate>Fri, 17 Apr 2026 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/books-wealth-freedom-road-reading-notes/</guid>
      <description>226个笔记 书籍作者：李笑来 说明：本文由 GA（GenericAgent）对整份读书笔记进行自动化整理、阅读友好增强，并发布到博客。 阅读友好增</description>
    </item>
    
    <item>
      <title>Android 使用 OpenSL ES 音频播放</title>
      <link>https://midFang.github.io/android-ffmpeg-opensl-es-play/</link>
      <pubDate>Sat, 06 Apr 2024 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/android-ffmpeg-opensl-es-play/</guid>
      <description>在上篇文章中，我们使用的是 Android 自带的 AudioTrack 来音频播放的，现在我们要切换成 OpenSL ES 来播放，那为什么要换成这个呢 ？ 一个方面是因为 OpenSL ES 性能会好一些，且都是在</description>
    </item>
    
    <item>
      <title>Android 使用 ffmpeg &#43; AudioTrack 音频播放</title>
      <link>https://midFang.github.io/android-ffmpeg-audiotrack-play/</link>
      <pubDate>Sat, 30 Mar 2024 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/android-ffmpeg-audiotrack-play/</guid>
      <description>在之前的文章中，我们已经编译好了 ffmpeg so 库了，本章中，我们开始使用它进行编解码音频播放，需要先了解一些前置知识 音视频前置知识和之前写的一些 C 代码</description>
    </item>
    
    <item>
      <title>Android 编译 ffmpeg</title>
      <link>https://midFang.github.io/android-compile-ffmpeg/</link>
      <pubDate>Mon, 25 Mar 2024 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/android-compile-ffmpeg/</guid>
      <description>前言 在上两篇文章中，我们已经学习了 CMake 和 Shell 的使用，接下来本篇文章开始对 ffmpeg 进行编译, 在编译开始之前 需要准备好 Linux 环境，下载 NDK，配置 NDK 环境变量等</description>
    </item>
    
    <item>
      <title>Android NDK 开发之 shell 脚本和交叉编译</title>
      <link>https://midFang.github.io/android-ndk-shell-and-cross-compile/</link>
      <pubDate>Sun, 17 Mar 2024 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/android-ndk-shell-and-cross-compile/</guid>
      <description>当编译过程比较复杂的时候, 我们就可以使用 shell 脚本来简化这个过程, 同时版本升级, 重复构建的基础上 shell 脚本也能够重复利用, 下面直接开始看看 shell 脚本是如</description>
    </item>
    
    <item>
      <title>Android NDK 开发之 cmake 使用</title>
      <link>https://midFang.github.io/android-ndk-cmake-simple-use/</link>
      <pubDate>Sun, 10 Mar 2024 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/android-ndk-cmake-simple-use/</guid>
      <description>在 Android NDK 开发中, CMake 是帮助我们来生成 makefle 文件的, 本文的示例是在 windows 中进行的, CMake 安装相关的可以参考本文 Windows10下配置CMake+Make+C</description>
    </item>
    
    <item>
      <title>你的大脑经历了什么</title>
      <link>https://midFang.github.io/what-happen-to-you/</link>
      <pubDate>Tue, 20 Feb 2024 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/what-happen-to-you/</guid>
      <description>你的大脑经历了什么 他像往常一样和女友正在散步逛街, 突然间的, 他听到了一个轰隆的声音，他表现的极其恐惧，身体不由自住的趴在地面上，仿佛他此时此</description>
    </item>
    
    <item>
      <title>Compose 绘制功能全解析</title>
      <link>https://midFang.github.io/compose-canvas-analysis/</link>
      <pubDate>Thu, 09 Nov 2023 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/compose-canvas-analysis/</guid>
      <description>最近项目中，针对 App 首次启动新手指引做了适配，新手指引大概的效果是如下图这样的，原本项目中使用的是纯图片，下方的箭头和小圆圈是固定显示在中间的</description>
    </item>
    
    <item>
      <title>Compose 滑动冲突解决</title>
      <link>https://midFang.github.io/compose-sliding-conflict-resolution/</link>
      <pubDate>Fri, 13 Oct 2023 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/compose-sliding-conflict-resolution/</guid>
      <description>在 Compose 中， 处理滑动冲突的 Api 是 Modifier.nestedScroll() 下面就让我们来看看 Compose 中是如何处理的 一般来说，滑动冲突本质是，滑动冲突是因为内外层组件在同一方向上都滑动，而系统并</description>
    </item>
    
    <item>
      <title>Compose 自定义绘制</title>
      <link>https://midFang.github.io/compose-custom-drawing/</link>
      <pubDate>Wed, 27 Sep 2023 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/compose-custom-drawing/</guid>
      <description>在 Compose 中，绘制的 Api 有 drawBehind drawWithContent 或者是使用完成自定义绘制方式 Canvas，接下来就来看看他们是如何使用的 在已有内容上绘制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15</description>
    </item>
    
    <item>
      <title>Compose 中的固有特性测量和自定义绘制顺序</title>
      <link>https://midFang.github.io/intrinsic-property-measurement-and-custom-plotting-order-in-compose/</link>
      <pubDate>Fri, 15 Sep 2023 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/intrinsic-property-measurement-and-custom-plotting-order-in-compose/</guid>
      <description>固有特性测量是什么 在解释固有特性测量是怎么之前，我们先看这样的例子 假设我们要实现上面的代码的效果，也就是中间线条的宽度是根据两边文字动态来计</description>
    </item>
    
    <item>
      <title>Compose LayoutModifier 原理解析</title>
      <link>https://midFang.github.io/compose-layoutmodifier-analysis/</link>
      <pubDate>Thu, 24 Aug 2023 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/compose-layoutmodifier-analysis/</guid>
      <description>LayoutModifier 作用是修改 Composable 的尺寸和位置偏移 LayoutModifier 只是一个接口，在实际开发中我们会使用 Modifier.layout() 自定义测量和位置偏移处理，先大致了解一下 layout 源码 1 2 3 4 5 6 7 8 9 10 11 12</description>
    </item>
    
    <item>
      <title>CombinedModifier 和 ComposedModifier 原理分析</title>
      <link>https://midFang.github.io/combinedmodifier-composedmodifier-analysis/</link>
      <pubDate>Thu, 20 Jul 2023 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/combinedmodifier-composedmodifier-analysis/</guid>
      <description>在 Compose 中，Modifier 的调用顺序不同，它造成的结果是不一样的，而不像原生的 XML 一样，顺序并不会影响界面绘制的结果。而在 Compose 中，它是按照Modi</description>
    </item>
    
    <item>
      <title>Compose 动画终章进阶篇</title>
      <link>https://midFang.github.io/compose-animation-final-chapter-advanced-chapter/</link>
      <pubDate>Wed, 05 Jul 2023 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/compose-animation-final-chapter-advanced-chapter/</guid>
      <description>AnimatedVisibility 对单个控件做显示和隐藏的动画效果 在上一个章节我们学习了 Transition 动画，这一节学习它更加上层的 Api，但其实内部本质上使用的也是 Transition, 先看一下 AnimatedVisibility 的源码,</description>
    </item>
    
    <item>
      <title>Compose转场动画之 Transition</title>
      <link>https://midFang.github.io/compose-transition/</link>
      <pubDate>Sun, 11 Jun 2023 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/compose-transition/</guid>
      <description>前言 在上两篇文章中，我们了解了 Compose 中动画的各种 animationSpec 的使用和 anim.xxx 的方法参数使用说明，这节开始学习 Transition 的使用 Transition 可对多个属性值进行动画 我们先通过一个例子来</description>
    </item>
    
    <item>
      <title>Compose之衰减型动画</title>
      <link>https://midFang.github.io/compose-animatedecay/</link>
      <pubDate>Tue, 30 May 2023 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/compose-animatedecay/</guid>
      <description>前言 回顾上篇文章我们学习了 compose 中的 animateTo 、 snapTo 如何使用，和 animationSpec 的参数配置等等，这篇文章，我们学习 Animatable 中另外一个方法 animateDecay animateDecay 衰减型动画， 它只有一个实现类 DecayAnimationSpecImpl 有了</description>
    </item>
    
    <item>
      <title>Compose 动画基础篇之各种 Spec</title>
      <link>https://midFang.github.io/compose-animation-basics/</link>
      <pubDate>Sat, 20 May 2023 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/compose-animation-basics/</guid>
      <description>从这一节开始，我们开始讲解 compose 最基础的动画 Api 使用，最基础也是最重要的部分，掌握这些基础的配置，会对后面的高阶动画的使用配置更加的得心应手 状态转</description>
    </item>
    
    <item>
      <title>线程池参数详解</title>
      <link>https://midFang.github.io/android-thread-pool/</link>
      <pubDate>Wed, 05 May 2021 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/android-thread-pool/</guid>
      <description>&lt;p&gt;这里直接拿 OKHttp 源码中的线程池举例：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;synchronized&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ExecutorService&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;executorService&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;executorService&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;executorService&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ThreadPoolExecutor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
          									&lt;span class=&#34;n&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 核心线程
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;                            &lt;span class=&#34;n&#34;&gt;Integer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;MAX_VALUE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 最大线程
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;                            &lt;span class=&#34;n&#34;&gt;60&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;					&lt;span class=&#34;c1&#34;&gt;// 空闲线程闲置时间
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;                            &lt;span class=&#34;n&#34;&gt;TimeUnit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;SECONDS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;	&lt;span class=&#34;c1&#34;&gt;// 闲置时间单位
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;                            &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SynchronousQueue&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Runnable&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 线程等待队列
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;                            &lt;span class=&#34;n&#34;&gt;Util&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;threadFactory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;OkHttp Dispatcher&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 线程创建工厂
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;      &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;executorService&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Socket 长连接通信实践与 NAT 超时</title>
      <link>https://midFang.github.io/android-socket-long-connection/</link>
      <pubDate>Tue, 04 May 2021 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/android-socket-long-connection/</guid>
      <description>&lt;h3 id=&#34;什么是socket&#34;&gt;什么是Socket？&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;即套接字，是一个对 TCP / IP协议进行封装 的编程调用接口（API）&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;socket通信模型&#34;&gt;Socket通信模型&lt;/h3&gt;

&lt;p&gt;&lt;img src=&#34;https://raw.githubusercontent.com/midFang/imgSource/main/202401141020583.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>HOOK 插件式一键换肤流程分析</title>
      <link>https://midFang.github.io/android-hook-change-skin/</link>
      <pubDate>Sun, 18 Apr 2021 00:00:00 +0000</pubDate>
      
      <guid>https://midFang.github.io/android-hook-change-skin/</guid>
      <description>&lt;h3 id=&#34;换肤流程&#34;&gt;换肤流程&lt;/h3&gt;

&lt;p&gt;首先实现插件式换肤需要知道以下几个流程：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;在默认情况下通过 setContentView 设置的资源布局（XML）是如何加载到界面上的&lt;/li&gt;
&lt;li&gt;在 Android 5.0 之前的版本和 5.0 之后的版本按钮是不一样的样式，系统是如何做到换肤的&lt;/li&gt;
&lt;li&gt;自定义换肤框架，如何知道我们自己的 APK 哪些控件是需要换肤的&lt;/li&gt;
&lt;li&gt;如何切换 【皮肤插件 / 默认】的肤色&lt;/li&gt;
&lt;li&gt;如何加载资源包插件&lt;/li&gt;
&lt;li&gt;重启 APP、进入其他 Activty 如何换肤&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    
  </channel>
</rss>