-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
114 lines (114 loc) · 24.2 KB
/
index.html
File metadata and controls
114 lines (114 loc) · 24.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="X-UA-Compatible" content="IE=edge"><title> Solartisan</title><meta name="description" content="A Blog Powered By Hexo"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="short icon" href="/favicon.png"><link rel="stylesheet" href="/css/apollo.css"><link rel="search" type="application/opensearchdescription+xml" href="http://solart.cc/atom.xml" title="Solartisan"></head><body><div class="wrap"><header><a href="/" class="logo-link"><img src="/logo.png"></a><ul class="nav nav-list"><li class="nav-list-item"><a href="/" target="_self" class="nav-list-link active">HOME</a></li><li class="nav-list-item"><a href="/archives/" target="_self" class="nav-list-link">ARCHIVE</a></li><li class="nav-list-item"><a href="https://github.com/solartisan" target="_blank" class="nav-list-link">GITHUB</a></li></ul></header><section class="container"><ul class="home post-list"><li class="post-list-item"><article class="post-block"><h2 class="post-title"><a href="/2023/01/23/compose-render-seq/" class="post-title-link">Compose 渲染过程分析</a></h2><div class="post-info">Jan 23, 2023</div><div class="post-content"><p>作者:<a href="mailto://imilko7@gmail.com">Oz</a></p>
<blockquote>
<p>版权声明:本文图文为博主原创,转载请注明出处。</p>
</blockquote>
<p><code>Compose</code> 作为一个新兴高效的 UI 框架,它使用声明式的语言来构建 UI,同时,它还使用惰性计算来优化 UI 的性能。目前在线上的业务中已经有了落地实践,例如实感骑容器、KS 等项目。正所谓知其然也要知其所以然,为了探究 <code>Compose</code> 的实现原理,对部分源码进行了阅读整理,这里尝试回答以下几个问题:</p>
<ul>
<li><p>作为一种新的 UI 框架它是如何将 <code>Compose UI</code> 渲染到屏幕上的?★★★★★</p>
</li>
<li><p>平常在写代码时,经常用到 <code>LaunchedEffect</code>、<code>SideEffect</code> 是怎么样生效的? ★</p>
</li>
<li><p><code>CompositionLocal</code> 通过 <code>@Composable</code> 函数隐式向下传递数据,它又是怎么样发挥作用的?★</p>
</li>
<li><p><code>@Composable</code> <code>AndroidView</code> 是怎么和 <code>Compose</code> 进行组合渲染的?★★</p>
</li>
</ul>
<h1 id="Pre-Start"><a href="#Pre-Start" class="headerlink" title="Pre-Start"></a>Pre-Start</h1><p>进入正题前,我们先看看官方的介绍:</p>
<blockquote>
<p><a href="https://developer.android.com/jetpack/compose/phases?hl=zh-cn">https://developer.android.com/jetpack/compose/phases?hl=zh-cn</a></p>
<p>与大多数其他界面工具包一样,Compose 会通过几个不同的“阶段”来渲染帧。如果我们观察一下 Android View 系统,就会发现它有 3 个主要阶段:<strong>测量、布局和绘制</strong>。Compose 和它非常相似,但开头多了一个叫做“组合”的重要阶段。</p>
<p><strong>帧的 3 个阶段</strong></p>
<p>Compose 有 3 个主要阶段:</p>
<ol>
<li><p><strong>组合</strong>:要显示什么样的界面。Compose 运行可组合函数并创建界面说明。</p>
</li>
<li><p><strong>布局</strong>:要放置界面的位置。该阶段包含两个步骤:测量和放置。对于布局树中的每个节点,布局元素都会根据 2D 坐标来测量并放置自己及其所有子元素。</p>
</li>
<li><p><strong>绘制</strong>:渲染的方式。界面元素会绘制到画布(通常是设备屏幕)中。</p>
</li>
</ol>
<p><img src="/images/compose-phases.png" alt="Compose Phases"></p>
</blockquote>
<p>以上,官方基本将渲染的关键流程讲出来了,但是还比较抽象。为了了解得更具体深入一些,我们有必要钻研一下 Compose 的源码。我们先来看一个实际使用的例子:</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">TestComposeActivity</span>: <span class="typename">ComponentActivity</span></span>() {</span><br><span class="line"></span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onCreate</span><span class="params">(savedInstanceState: <span class="typename">Bundle?</span>)</span> {</span></span><br><span class="line"> super.onCreate(savedInstanceState)</span><br><span class="line"> setContent {</span><br><span class="line"> Text(text = <span class="string">"Hello World!"</span>)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>以上实际画的内容是什么并不重要,重要的是我们从 <code>setContent</code> 这个入口追踪一下流程中发生了什么。</p>
<h1 id="1-1-Compose-环境初始化"><a href="#1-1-Compose-环境初始化" class="headerlink" title="1.1 Compose 环境初始化"></a>1.1 Compose 环境初始化</h1><p>首先,为了更快的让大家了解 <code>setContent</code> 这个过程发生了什么,我们可以先看整理好的流程图:</p>
<p><img src="/images/compose-create-composition.png" alt="compose-create-composition.png"></p>
<p>下面我们来通过代码流程,看下这里面都做了哪些事。</p></div><a href="/2023/01/23/compose-render-seq/" class="read-more">...阅读全文</a></article></li><li class="post-list-item"><article class="post-block"><h2 class="post-title"><a href="/2020/07/17/nested_ceiling_effect/" class="post-title-link">也许是最贴近京东首页体验的嵌套滑动吸顶效果</a></h2><div class="post-info">Jul 17, 2020</div><div class="post-content"><p>作者:<a href="mailto://imilko7@gmail.com">Oz</a></p>
<p>v 信号: <code>Mojitok8275</code></p>
<blockquote>
<p>版权声明:本文图文为博主原创,转载请注明出处。</p>
</blockquote>
<p>吸顶效果是各家 App 或多或少都会用的一个交互,这种交互也常见于 PC、H5,可以说是一种通用性很强的前端交互体验,相比较来说京东首页的嵌套滑动吸顶效果是各个类似效果中体验比较好的一个,因为在嵌套布局中滑动连贯性处理得非常好,今天我们就来实现同样的交互效果。</p>
<h3 id="这篇文章我会讲些什么"><a href="#这篇文章我会讲些什么" class="headerlink" title="这篇文章我会讲些什么"></a>这篇文章我会讲些什么</h3><ul>
<li>对于吸附效果实现的思路</li>
<li>3 个版本的 NestedScrollingParent、NestedScrollingChild 简单介绍</li>
<li>嵌套组件滑动连贯性(一致性)的处理(事件分发、Fling 等)</li>
<li>交互的优化问题</li>
</ul>
<p>首先,先看一下我们实现的效果图:</p>
<p><img src="/images/nested_live.gif" width=220></p>
<p>这里只介绍我们实现过程中的思路,以及部分代码,源码请查看 <a href="https://github.com/solartcc/NestedCeilingEffect">NestedCeilingEffect</a>,欢迎建议、Issues、Star</p>
<h2 id="1、实现滑动吸顶效果的简单分析"><a href="#1、实现滑动吸顶效果的简单分析" class="headerlink" title="1、实现滑动吸顶效果的简单分析"></a>1、实现滑动吸顶效果的简单分析</h2><p>对于吸顶效果,首先我们要先创造出 <code>“顶”</code> 来,那么如何创造 <code>“顶”</code> 呢?常见的实现方式有很多,比如:</p>
<ul>
<li>通过两个相同的顶部控件显示或隐藏来实现</li>
<li>通过动态 layout 顶部控件来实现</li>
<li>通过重写 ItemDecoration 来实现</li>
<li>通过 CoordinatorLayout 协调子布局来实现</li>
</ul>
<p>这些方式或多或少在某些方面有一些场景上的限制,这次我们采用另外一种方式来实现 <code>“顶”</code> 的效果,这里先卖一个关子。</p></div><a href="/2020/07/17/nested_ceiling_effect/" class="read-more">...阅读全文</a></article></li><li class="post-list-item"><article class="post-block"><h2 class="post-title"><a href="/2020/07/02/trie_queue/" class="post-title-link">前缀树 + 队列处理通配符查找</a></h2><div class="post-info">Jul 2, 2020</div><div class="post-content"></div><a href="/2020/07/02/trie_queue/" class="read-more">...阅读全文</a></article></li><li class="post-list-item"><article class="post-block"><h2 class="post-title"><a href="/2020/06/16/understand_rxjava2/" class="post-title-link">两张图彻底理解 RxJava2 的核心原理</a></h2><div class="post-info">Jun 16, 2020</div><div class="post-content"><p>作者:<a href="mailto://imilko7@gmail.com">Oz</a></p>
<p>v 信号: <code>Mojitok8275</code></p>
<blockquote>
<p>版权声明:本文图文为博主原创,转载请注明出处。</p>
</blockquote>
<p>文章似乎有些标题党的嫌疑,但是我相信根据我的理解画出两幅图可以让大家理解 RxJava2 的核心原理,稍后不要吝啬,请叫我灵魂画手😄!相信 <code>RxJava</code> 是大家业务中用到比较多的一个依赖库,RxJava 的强大之处在于它改变了程序员的编程习惯,相比较其他的开源项目,Rxjava 是最弯弯绕的一个。对于 RxJava 种类繁多的操作符,大多数同学都表示很是头疼,也有不少同学陷入了学习操作符不能停的怪圈。操作符要不要学,当然要,但是如果能理解 RxJava 的核心,操作符的使用就像是学会九阳神功的张无忌学招数,必定是手到擒来。所谓器欲尽其用,必先得其法。</p>
<h3 id="这篇文章我会讲些什么"><a href="#这篇文章我会讲些什么" class="headerlink" title="这篇文章我会讲些什么"></a>这篇文章我会讲些什么</h3><ul>
<li>RxJava2 基本的运行流程</li>
<li>RxJava2 线程切换的原理(涉及到为什么 subscribeOn() 只有第一次调用时有效)</li>
<li>为什么一订阅就回调了 onSubscribe</li>
<li>为什么 subscribeOn() 对上面的代码生效,observerOn() 对下面代码生效</li>
</ul>
<p>以下内容如果涉及到自己写的代码我会采用 Kotlin 进行示例展示,涉及到 RxJava2 会展示部分源码。</p>
<h2 id="1、简单的链式调用(无线程切换)"><a href="#1、简单的链式调用(无线程切换)" class="headerlink" title="1、简单的链式调用(无线程切换)"></a>1、简单的链式调用(无线程切换)</h2></div><a href="/2020/06/16/understand_rxjava2/" class="read-more">...阅读全文</a></article></li><li class="post-list-item"><article class="post-block"><h2 class="post-title"><a href="/2018/07/07/gradle-migrate-3.0.0+/" class="post-title-link">Gradle Plugin 升级迁移及构建优化</a></h2><div class="post-info">Jul 7, 2018</div><div class="post-content"><p>作者:<a href="mailto://imilko7@gmail.com">Oz</a></p>
<blockquote>
<p>版权声明:转载请注明出处。</p>
</blockquote>
<p>一直以来,Android 项目在构建速度是一大槽点,随着Android Studio 3.0 的大版本的升级使得多Module工程的构建速度加快很多。这主要依赖于 Android Plugin for Gradle 插件版本的升级,因此部分 API 发生了较大变化。本文主要是记录整个迁移过程以及聊一些常用的优化构建速度的建议,以供参考。</p>
<blockquote>
<p>android studio 3.1.3; gradle-4.4; gradle plugin 3.1.3 </p>
</blockquote>
<h2 id="1、Android-SDK-构建系统"><a href="#1、Android-SDK-构建系统" class="headerlink" title="1、Android SDK 构建系统"></a>1、Android SDK 构建系统</h2><p>在正式讲述升级迁移之前,大家应该熟悉一下 Android SDK 的构建系统,Android 构建系统编译应用资源和源代码,然后将它们打包成可供开发人员测试、部署、签署和分发的 APK。Android Studio 使用 <a href="http://www.gradle.org/">Gradle</a> 这一高级构建工具包来自动化执行和管理构建流程,同时也允许开发人员定义灵活的自定义构建配置。每个构建配置均可自行定义一组代码和资源,同时对所有应用版本共有的部分加以重复利用。Android Plugin for Gradle 与这个构建工具包协作,共同提供专用于构建和测试 Android 应用的流程和可配置设置。 </p></div><a href="/2018/07/07/gradle-migrate-3.0.0+/" class="read-more">...阅读全文</a></article></li><li class="post-list-item"><article class="post-block"><h2 class="post-title"><a href="/2017/08/20/react-native-render-seq/" class="post-title-link">React Native渲染流程浅析</a></h2><div class="post-info">Aug 20, 2017</div><div class="post-content"><p>作者:<a href="mailto://imilko7@gmail.com">Oz</a></p>
<blockquote>
<p>版权声明:本文图文为博主原创,转载请注明出处。</p>
</blockquote>
<p>随着跨平台技术的发展演进,<code>React Native</code> 被越来越多的公司所接受,因此在这里分享一下 <code>React Native</code> 渲染流程,希望能帮助大家对 <code>React Native</code> 进行更深入的理解。</p>
<h2 id="1、跨平台框架"><a href="#1、跨平台框架" class="headerlink" title="1、跨平台框架"></a>1、跨平台框架</h2><p>跨平台一直以来是一个工程实践上的真实需求,用来节约项目开发的人力成本、时间成本等,尤其是在当下移动互联网的时代。在 <code>React Native</code> 诞生之前,已经存在了很多跨平台的方案,例如:<code>Phone Gap</code> 、<code>Xamarin</code> 、<code>Corona</code> 等。</p>
<h4 id="1-1-跨平台框架都是伪命题?"><a href="#1-1-跨平台框架都是伪命题?" class="headerlink" title="1.1 跨平台框架都是伪命题?"></a>1.1 跨平台框架都是伪命题?</h4><ul>
<li><a href="http://phonegap.com/">PhoneGap</a> 利用 open-web 技术,即 HTML 5、CSS3 以及 JavaScript 构建移动 Web 应用。</li>
<li><a href="https://www.xamarin.com/">Xamarin</a> 利用 C# 语言开发原生移动应用,打包时将 C# 转化为对应平台的原生代码。</li>
<li><a href="https://coronalabs.com/">Corona</a> 2D 游戏与应用开发平台,利用 lua 进行开发,主要面向游戏开发。</li>
</ul>
<p>在以上我们提到这个几个跨平台框架,相对来说是被采用较多或比较知名的,但也缺点十分明显。其实在接触 <code>React Native</code> 之前我一直都认为所谓跨平台框架都是伪命题,但是在接触之后,确实改变了我的认识。</p>
<h4 id="1-2-基于-JS-的跨平台框架"><a href="#1-2-基于-JS-的跨平台框架" class="headerlink" title="1.2 基于 JS 的跨平台框架"></a>1.2 基于 JS 的跨平台框架</h4><p><code>Facebook</code>在 <code>React.js Conf 2015</code> 大会上推出了基于 <code>JavaScript</code> 的开源框架 <code>React Native</code>。</p>
<p><code>React Native</code> 结合了 <code>Web</code> 应用和 <code>Native</code> 应用的优势,可以使用 <code>JavaScript</code> 来开发 <code>iOS</code> 和 <code>Android</code> 原生应用。在 <code>JavaScript</code> 中用 <code>React</code> 抽象操作系统原生的 UI 组件,代替 DOM 元素来渲染。这种方案与类似 <code>PhoneGap</code> 这种依赖 open-web 技术方案最大的不同就是 <code>React Native</code> 会将标签元素渲染成原生 UI 组件,从而提升性能及交互体验,使得应用本身更加接近原生应用的体验,也因此有越来越多的公司开始考虑 <code>React Native</code> 的跨平台方案。</p></div><a href="/2017/08/20/react-native-render-seq/" class="read-more">...阅读全文</a></article></li><li class="post-list-item"><article class="post-block"><h2 class="post-title"><a href="/2017/03/18/stardard_js/" class="post-title-link">stardard JS 代码规范及 pre-commit hook</a></h2><div class="post-info">Mar 18, 2017</div><div class="post-content"><p>作者:<a href="mailto://imilko7@gmail.com">Oz</a></p>
<blockquote>
<p>版权声明:本文为博主原创,转载请注明出处。</p>
</blockquote>
<p>今天主要安利一个 JavaScript 代码规范 <a href="http://standardjs.com/">standard js</a> ,不论你一开始喜不喜欢这个标准,相信我开使用它,你会爱上这个标准!</p>
<h2 id="1、序言"><a href="#1、序言" class="headerlink" title="1、序言"></a>1、序言</h2><p>是的最近团队一直在 <code>React Native</code> 上进行探索性业务开发,在团队项目的合作中代码规范对于我们是一个相当重要的素质要求,对于注重代码质量注重代码可读性的团队尤其重要。由于缺乏代码规范,不同的人有不同的偏好,代码可读性会随着团队成员的更迭逐渐降低,也因为这样有可能带来线上 bug,而这些完全是可以通过代码检查避免的。</p>
<h2 id="2、是时候强制要求代码规范了"><a href="#2、是时候强制要求代码规范了" class="headerlink" title="2、是时候强制要求代码规范了"></a>2、是时候强制要求代码规范了</h2><p> <code>强制</code>两个字是好说不好听,谁也不愿意被强制要求这样那样,但这个事情我觉得懂的人自然懂,没什么好说的,团队合作就应该采用相同的规范,不同的人写的代码应该看起来是出自同一个人之手。</p></div><a href="/2017/03/18/stardard_js/" class="read-more">...阅读全文</a></article></li><li class="post-list-item"><article class="post-block"><h2 class="post-title"><a href="/2017/02/22/react-native-jsbundle-patch/" class="post-title-link">React Native拆包及热更新方案</a></h2><div class="post-info">Feb 22, 2017</div><div class="post-content"><p>作者:<a href="mailto://imilko7@gmail.com">Oz</a></p>
<blockquote>
<p>版权声明:本文图文为博主原创,转载请注明出处。</p>
</blockquote>
<p>随着 <code>React Native</code> 的不断发展完善,越来越多的公司选择使用 <code>React Native</code> 替代 <code>iOS/Android</code> 进行部分业务线的开发,也有不少使用 <code>Hybrid</code> 技术的公司转向了 <code>React Native</code> 。要说 <code>React Native</code> 最能吸引开发者的地方那就是其拥有前端的开发速度以及原生的体验。</p>
<h2 id="1、序言"><a href="#1、序言" class="headerlink" title="1、序言"></a>1、序言</h2><p>今天要跟大家探讨的是 <code>React Native</code> 的拆包及热更新方案,官方并没有很好的支持这一企业十分看中的热更新能力,因此也催生了第三方的热更新方案,如 <a href="https://microsoft.github.io/code-push/docs/react-native.html">CodePush</a> 、 <a href="https://github.com/reactnativecn/react-native-pushy">react-native-pushy</a> 。由于公司内部有不同的业务线,所以在采用第三方的热更新方案灵活度不够,在调研的初期,我们参考了携程的提到的 <code>jsbundle</code> <a href="https://zhuanlan.zhihu.com/p/23715716">拆分和加载优化方案</a>,但这个方案需要改变 <code>React Native</code> 的打包代码及 <code>Runtime</code> 代码,实施难度上非常大,暂无精力深入研究,但这个方案对加载速度提升也是显而易见的。我们暂时放弃了携程的方案,我们前期需要一套相对简单稳定且可行度高的方案,在经过调研及讨论后定下了这样一套热更方案,今天我们就来聊聊这个方案。</p></div><a href="/2017/02/22/react-native-jsbundle-patch/" class="read-more">...阅读全文</a></article></li><li class="post-list-item"><article class="post-block"><h2 class="post-title"><a href="/2017/01/23/react-native-custom-view/" class="post-title-link">可能是最in的React Native使用原生自定义下拉刷新组件教程</a></h2><div class="post-info">Jan 23, 2017</div><div class="post-content"><p>作者:<a href="mailto://imilko7@gmail.com">Oz</a></p>
<blockquote>
<p>版权声明:本文图文为博主原创,转载请注明出处。</p>
</blockquote>
<p>在 2016 年移动端跨平台开发是几个最热的技术之一,相信在 2017 年这股热潮将持续发酵。为什么这么说呢,因为随着业务的爆发式增长,传统的原生开发模式有点显得跟不上节奏了,这也促使各个公司希望寻找到一个更加高效的开发方案,当下可以被选择的方案中,<code>React Native</code> 及 <code>Weex</code> 都是不错的技术方案。在年前团队内部的一场 <code>React Native vs Weex</code> 的技术对垒中本来我选择的是 <code>Weex</code> 的阵营,但当时在多维的技术指标中新生的 <code>Weex</code> 还是不敌 <code>React Native</code> ,团队内部最终敲定了采用 <code>React Native</code> 跨平台方案。</p>
<h2 id="1、概述"><a href="#1、概述" class="headerlink" title="1、概述"></a>1、概述</h2><p>闲话不多说,这里的主要目的是跟大家聊聊 <code>React Native</code> 在 <code>Android</code> 平台使用原生自定义 <code>View</code> ,这里默认大家对 <code>React Native</code> 已经有一定的了解,<code>React Native</code> 中的组件都是基于 <code>iOS/Android</code> 的官方组件进行封装,所以在一些特别的场景下并不能很好的满足需求。正如标题中的下拉刷新组件,<code>React Native</code> 在 <code>Android</code> 平台采用的是 <code>android.support.v4.widget.SwipeRefreshLayout</code> ,一些 <code>iOS</code> 设计优先的团队(譬如我司)而言对于 <code>Android</code> 开发人员简直就是灾难。在众多开源的 <code>React Native</code> 项目中大家也不会再这些细节上较真,但是公司的 <code>UED</code> 这关可不好过。</p></div><a href="/2017/01/23/react-native-custom-view/" class="read-more">...阅读全文</a></article></li><li class="post-list-item"><article class="post-block"><h2 class="post-title"><a href="/2016/12/06/keep_alive_push/" class="post-title-link">都是 Push 惹的祸</a></h2><div class="post-info">Dec 6, 2016</div><div class="post-content"><p>作者:<a href="mailto://imilko7@gmail.com">Oz</a></p>
<blockquote>
<p>版权声明:本文图文为博主原创,转载请注明出处。</p>
</blockquote>
<p>这是一篇 KPI 考核背景下产出的文章,这一切都起源于我司要求提升 App 推送送达率,以节省在短信推广上花费的开销。这里记录了在整个技术调研的关键点。</p>
<h2 id="1、概述"><a href="#1、概述" class="headerlink" title="1、概述"></a>1、概述</h2><p><code>iOS</code> 和 <code>Android</code> 均在系统级集成了推送服务,来说说<code>原生 Android</code> 的推送服务,最在 Android 2.2 时,<code>C2DM</code> 作为系统级服务集成进了 <code>Android</code> 系统,而 <code>GCM(Google Clould Messaging)</code> 在 2013 Google IO 大会发布后就正式取代了 <code>C2DM</code> ,然后 Google 并没有止步,在 2014 年收购了 <a href="https://en.wikipedia.org/wiki/Firebase"><code>Firebase</code></a> ,经过近两年的整合,在 2016 年 Google IO 大会上隆重发布了 Firebase 服务,一个全新的移动和 Web 开发的完整后端解决方案,其中就包括了<code>FCM(Firebase Cloud Messaging)</code>。如果就这么简单,我们就可以在 Android 平台上像 iOS 平台一样使用系统级共享的推送服务了,然而一股神秘的东方力量打破了原本简单的事情…</p></div><a href="/2016/12/06/keep_alive_push/" class="read-more">...阅读全文</a></article></li></ul></section><footer><div class="paginator"><a href="/page/2/" class="next">下一页</a></div><div class="copyright"><p>© 2015 - 2024 <a href="http://solart.cc">Oz</a>, powered by <a href="https://hexo.io/" target="_blank">Hexo</a> and <a href="https://github.com/pinggod/hexo-theme-apollo" target="_blank">hexo-theme-apollo</a>.</p></div></footer></div><script async src="//cdn.bootcss.com/mathjax/2.6.1/MathJax.js?config=TeX-MML-AM_CHTML"></script><script>(function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;e=o.createElement(i);r=o.getElementsByTagName(i)[0];e.src='//www.google-analytics.com/analytics.js';r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));ga('create',"UA-51018462-1",'auto');ga('send','pageview');</script></body></html>