-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
134 lines (63 loc) · 63.5 KB
/
search.xml
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>Lifecycle 的使用</title>
<link href="/2021/06/28/Lifecycle-%E4%B8%8E-LiveData-%E7%9A%84%E4%BD%BF%E7%94%A8/"/>
<url>/2021/06/28/Lifecycle-%E4%B8%8E-LiveData-%E7%9A%84%E4%BD%BF%E7%94%A8/</url>
<content type="html"><![CDATA[<h3 id="Lifecycle"><a href="#Lifecycle" class="headerlink" title="Lifecycle"></a>Lifecycle</h3><p>Lifecycle 是一个组件库,而该组件库中又包含 Lifecycle 这个类。Lifecycle 类主要是便于开发者管理 Activity 与 Fragment 的生命周期。</p><p>在 Activity 中感受生命周期比较简单,只需要重写对应的方法,在其中进行的相应的感知操作(如写日志)等便可以清楚的感知到其处于生命周期的哪个阶段。但是不在 Activity 中时(非 Activity 类),感知其生命周期,常用的方式有:在 Activity 中嵌入一个 Fragment;写监听器(分为未使用 Lifecycles 组件与使用该组件两种)。</p><p>其中不使用组件通常做法为:</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><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyObserver</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 感知 activity 的 onStart</span></span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">activityStart</span><span class="params">()</span></span> {</span><br><span class="line"> Log.d(<span class="string">"MyObserver"</span>, <span class="string">"activityStart"</span>)</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 感知 activity 的 onStop</span></span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">activityStop</span><span class="params">()</span></span> {</span><br><span class="line"> Log.d(<span class="string">"MyObserver"</span>, <span class="string">"activityStop"</span>)</span><br><span class="line"> }</span><br><span class="line"> .</span><br><span class="line"> .</span><br><span class="line"> .</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>你还可以实现对应的其它五个生命周期的方法,但是使用此方式还是需要在对应的 Activity 中重写对应于你监听的生命周期方法,比较繁琐。</p><p>使用 Lifecycles 的组件常见的做法如下:首先对写的监听类实现 <code> LifecycleObserver</code> 接口,然后在对应的生命周期方法上加上对应的 <code>@OnLifecycleEvent</code> 注解,注解内传入参数为对应的生命周期事件,生命周期事件可分为<code>6 + 1</code>,其中的 <code>6</code> 为:ON_CREATE、ON_START、ON_RESUME、ON_PAUSE、ON_STOP、ON_DESTROY,其分别对应与 Activity 中的那些生命周期;<code>1</code> 则是 ON_ANY,其可以对应与 Activity 的任何生命周期。实例如下:</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><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyObserver</span> : <span class="type">LifecycleObserver {</span></span></span><br><span class="line"></span><br><span class="line"> <span class="meta">@OnLifecycleEvent(Lifecycle.Event.ON_START)</span></span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">activityStart</span><span class="params">()</span></span> {</span><br><span class="line"> Log.d(<span class="string">"MyObserver"</span>, <span class="string">"activityStart"</span>)</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@OnLifecycleEvent(Lifecycle.Event.ON_STOP)</span></span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">activityStop</span><span class="params">()</span></span> {</span><br><span class="line"> Log.d(<span class="string">"MyObserver"</span>, <span class="string">"activityStop"</span>)</span><br><span class="line"> }</span><br><span class="line"> .</span><br><span class="line"> .</span><br><span class="line"> .</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>然后需要使用 LifecycleOwner 对象获取到 lifecycle 对象,再使用获取到的对象的的 addObserver() 方法使得在 Activity 的生命周期发生变化时,MyObserver 可以得到通知。格式如下:</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">LifecycleOwner().lifecycle.addObserver(监听器实例)</span><br></pre></td></tr></table></figure><p>此外,只要 Activity 是继承自 AppCompatActivity,或者 Fragment 是继承自 Androidx 中的 Fragment(androidx.fragment.app.Fragment),该 Activity 与 Fragment 本身便是一个 LifecycleOwner 的实例 ,因此可以直接得到 Lifecycle 实例。具体类图如下图所示:</p><figure class="highlight plaintext"><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><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">classDiagram</span><br><span class="line">FragmentActivity <|-- AppCompatActivity: extends</span><br><span class="line">ComponentActivity <|-- FragmentActivity: extends</span><br><span class="line">LifecycleOwner <|.. ComponentActivity: implements</span><br><span class="line">LifecycleOwner <|.. Fragment: implements</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">class FragmentActivity {</span><br><span class="line">+String TAG</span><br><span class="line">+...</span><br><span class="line">+getLifecycle() Lifecycle</span><br><span class="line">}</span><br><span class="line">class AppCompatActivity {</span><br><span class="line">+AppCompatDelegate mDelegate</span><br><span class="line">+Resources mResources</span><br><span class="line">+attachBaseContext(Context newBase) void</span><br><span class="line">+...()</span><br><span class="line">}</span><br><span class="line">class Fragment {</span><br><span class="line">+getLifecycle() Lifecycle</span><br><span class="line">}</span><br><span class="line"> </span><br></pre></td></tr></table></figure><p>然后可以直接调用 addObserver(),并传入监听器实例即可,除了上述所说的直接得到的方法之外,也可以自己实现 LifecycleOwner 。</p><p>示例如下,在 MainActivity 中加入 <code>lifecycle.addObserver(MyObserver())</code> 即可 。</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></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> : <span class="type">AppCompatActivity</span></span>() {</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="type">Bundle</span>?)</span></span> {</span><br><span class="line"> <span class="keyword">super</span>.onCreate(savedInstanceState)</span><br><span class="line"> setContentView(R.layout.activity_main)</span><br><span class="line"></span><br><span class="line"> lifecycle.addObserver(MyObserver())</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>参考:</p><p><a href="https://juejin.cn/post/6893870636733890574">“终于懂了“系列:Jetpack AAC完整解析(一)Lifecycle 完全掌握! (juejin.cn)</a></p><p>郭霖. 第一行代码 Android[M]. 第三版. 北京: 人民邮电出版社. 2020. 541-545.</p>]]></content>
<tags>
<tag> Android </tag>
</tags>
</entry>
<entry>
<title>NavigationView 与 DrawerLayout 的使用(Kotlin)</title>
<link href="/2021/06/25/NavigationView-%E4%B8%8E-DrawerLayout-%E7%9A%84%E4%BD%BF%E7%94%A8/"/>
<url>/2021/06/25/NavigationView-%E4%B8%8E-DrawerLayout-%E7%9A%84%E4%BD%BF%E7%94%A8/</url>
<content type="html"><![CDATA[<p>[TOC]</p><h2 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h2><h3 id="DrawerLayout-介绍"><a href="#DrawerLayout-介绍" class="headerlink" title="DrawerLayout 介绍"></a>DrawerLayout 介绍</h3><p><code>DrawerLayout</code> 是一种布局,可以实现两个界面,一个是主屏幕,另一个是通过滑动的方式将一些隐藏的菜单显示出来,最显著的例子便是 Google play store。<code>DrawerLayout</code> 的布局文件中可以放两个同级的控件,其中第一个为主屏幕的显示内容,第二个为侧边滑动菜单的显示内容。形式如下:</p><figure class="highlight xml"><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><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><?xml version="1.0" encoding="utf-8"?></span></span><br><span class="line"><span class="tag"><<span class="name">androidx.drawerlayout.widget.DrawerLayout</span> <span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">xmlns:app</span>=<span class="string">"http://schemas.android.com/apk/res-auto"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">xmlns:tools</span>=<span class="string">"http://schemas.android.com/tools"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/drawerLayout"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">tools:context</span>=<span class="string">".MainActivity"</span>></span></span><br><span class="line"></span><br><span class="line"> <主屏幕的布局内容></span><br><span class="line"> .</span><br><span class="line"> .</span><br><span class="line"> </主屏幕的布局内容></span><br><span class="line"></span><br><span class="line"> <侧边滑动菜单的布局内容</span><br><span class="line"> android:layout_gravity="start" /></span><br><span class="line"></span><br><span class="line"><span class="tag"></<span class="name">androidx.drawerlayout.widget.DrawerLayout</span>></span></span><br></pre></td></tr></table></figure><p>注意,滑动菜单中必须指定<code>android:layout_gravity=""</code>,这代表该菜单所属的位置在左边还是右边。</p><h3 id="NavigationView-介绍"><a href="#NavigationView-介绍" class="headerlink" title="NavigationView 介绍"></a>NavigationView 介绍</h3><p>想要实现 Google play store 的滑动菜单的样式,可以使用<code>NavigationView</code>来实现,该控件可以大致分为上下两个部分,上面的区域为<code>HeaderView</code>,下面的区域为具体的菜单选项分布。</p><h2 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h2><p>文中会使用将图片圆形化的方式展示用户的头像,因此需要在<code>app/build.gradle</code>中添加依赖:</p><figure class="highlight xquery"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">implementation <span class="string">'de.hdodenhof:circleimageview:3.0.1'</span></span><br></pre></td></tr></table></figure><p>在实现 NavigationView 之前首先准备 menu 与 headerLayout 两个部分</p><ul><li><p>menu 实现:</p><ul><li><p>首先为了展示菜单选项左边的图标,首先需要准备好相应的素材,这里使用图标库自带的图标(在 drawable 文件夹上右击新建一个<code>Verctor Asset</code>,再选择<code>Asset Type</code>中的<code>Clip Art</code>,最后点击下面<code>Clip Art</code>右边的图标即可选择自带图标库中的图标)。</p></li><li><p>右键点击<code>res</code>新建文件夹名为 <code>menu</code>的文件夹,在 <code>menu</code>中新建文件(文件及类型名为:<code>nav_menu.xml</code>),内容为:</p><figure class="highlight xml"><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><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><?xml version="1.0" encoding="UTF-8" ?></span></span><br><span class="line"><span class="tag"><<span class="name">menu</span> <span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">group</span> <span class="attr">android:checkableBehavior</span>=<span class="string">"single"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">item</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/myAppAndGames"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:icon</span>=<span class="string">"@drawable/ic_baseline_apps_24"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:title</span>=<span class="string">"My app <span class="symbol">&amp;</span> games"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">item</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/notification"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:icon</span>=<span class="string">"@drawable/ic_baseline_notifications_24"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:title</span>=<span class="string">"Notification"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">item</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/subscription"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:icon</span>=<span class="string">"@drawable/ic_baseline_subscriptions_24"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:title</span>=<span class="string">"Subscription"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">item</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/wishList"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:icon</span>=<span class="string">"@drawable/ic_baseline_format_list_bulleted_24"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:title</span>=<span class="string">"Wishlist"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">item</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/account"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:icon</span>=<span class="string">"@drawable/ic_baseline_account_circle_24"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:title</span>=<span class="string">"Account"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">item</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/paymentMethods"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:icon</span>=<span class="string">"@drawable/ic_baseline_payment_24"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:title</span>=<span class="string">"Payment methods"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">item</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/playProtect"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:icon</span>=<span class="string">"@drawable/ic_baseline_admin_panel_settings_24"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:title</span>=<span class="string">"Play protect"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">item</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/settings"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:icon</span>=<span class="string">"@drawable/ic_baseline_settings_24"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:title</span>=<span class="string">"Settings"</span> /></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"></<span class="name">group</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"></<span class="name">menu</span>></span></span><br></pre></td></tr></table></figure></li></ul></li><li><p>headerLayout 实现:</p><ul><li><p>准备侧边栏上边部分的 HeaderLayout,右击 layout 文件夹新建文件名为 nav_header.xml 的文件,文件内容如下:</p><figure class="highlight xml"><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><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><?xml version="1.0" encoding="utf-8"?></span></span><br><span class="line"><span class="tag"><<span class="name">RelativeLayout</span> <span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"180dp"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:background</span>=<span class="string">"@color/colorPrimary"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:padding</span>=<span class="string">"10dp"</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">de.hdodenhof.circleimageview.CircleImageView</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/iconImage"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"70dp"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"70dp"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_centerVertical</span>=<span class="string">"true"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:src</span>=<span class="string">"@drawable/header"</span> /></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">TextView</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/email"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"wrap_content"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_alignParentBottom</span>=<span class="string">"true"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"tonygreendev@gmail.com"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:textColor</span>=<span class="string">"#FFF"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:textSize</span>=<span class="string">"14sp"</span> /></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">TextView</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/userName"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"wrap_content"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_above</span>=<span class="string">"@id/email"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"Tony Green"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:textColor</span>=<span class="string">"#FFF"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:textSize</span>=<span class="string">"14sp"</span> /></span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="tag"></<span class="name">RelativeLayout</span>></span></span><br></pre></td></tr></table></figure></li></ul></li></ul><p>上面内容全部实现后即可使用 DrawerLayout + NavigationView 实现 Google play store 的效果,下面是<code>activity_main.xml</code>布局文件中的内容</p><figure class="highlight xml"><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><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><?xml version="1.0" encoding="utf-8"?></span></span><br><span class="line"><span class="tag"><<span class="name">androidx.drawerlayout.widget.DrawerLayout</span> <span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">xmlns:app</span>=<span class="string">"http://schemas.android.com/apk/res-auto"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">xmlns:tools</span>=<span class="string">"http://schemas.android.com/tools"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/drawerLayout"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">tools:context</span>=<span class="string">".MainActivity"</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">LinearLayout</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:orientation</span>=<span class="string">"vertical"</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">androidx.appcompat.widget.Toolbar</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/toolbar"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"?attr/actionBarSize"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:background</span>=<span class="string">"@color/colorPrimary"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:theme</span>=<span class="string">"@style/ThemeOverlay.AppCompat.Dark.ActionBar"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">app:popupTheme</span>=<span class="string">"@style/ThemeOverlay.AppCompat.Light"</span> /></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">Button</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/getAppDataBtn"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"get app data"</span> /></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">Button</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/nextActivityBtn"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"next activity"</span> /></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"></<span class="name">LinearLayout</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">com.google.android.material.navigation.NavigationView</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/navView"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_gravity</span>=<span class="string">"start"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">app:headerLayout</span>=<span class="string">"@layout/nav_header"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">app:menu</span>=<span class="string">"@menu/nav_menu"</span> /></span></span><br><span class="line"></span><br><span class="line"><span class="tag"></<span class="name">androidx.drawerlayout.widget.DrawerLayout</span>></span></span><br></pre></td></tr></table></figure><p>上述布局中两个平行的控件布局分别为:LinearLayout 与 NavigationView,其中 NavigationView 中通过指定<code>app:headerLayout="@layout/nav_header"</code> 与 <code>app:menu="@menu/nav_menu"</code> 来说明侧边滑动菜单栏的上下两个部分的布局内容。</p><p>本文使用了视图绑定,减少样板代码 <code>findViewById()</code> ,使用此功能需要在<code> app/build.gradle</code> 中添加如下代码</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">viewBinding {</span><br><span class="line"> enabled = true</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p>最后在 MainAcivity 中实现相应的操作逻辑,代码如下:</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><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> : <span class="type">AppCompatActivity</span></span>() {</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">lateinit</span> <span class="keyword">var</span> binding: ActivityMainBinding</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="type">Bundle</span>?)</span></span> {</span><br><span class="line"> <span class="keyword">super</span>.onCreate(savedInstanceState)</span><br><span class="line"> binding = inflate(layoutInflater)</span><br><span class="line"> setContentView(binding.root)</span><br><span class="line"> setSupportActionBar(binding.toolbar)</span><br><span class="line"></span><br><span class="line"> binding.getAppDataBtn.setOnClickListener {</span><br><span class="line"> <span class="comment">// button 操作逻辑</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> binding.nextActivityBtn.setOnClickListener {</span><br><span class="line"> <span class="comment">// button 操作逻辑</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 使得点击最左边的三道杠显示滑动菜单栏,不实现此部分可以左右滑动来显示或隐藏滑动菜单栏</span></span><br><span class="line"> supportActionBar?.let {</span><br><span class="line"> it.setDisplayHomeAsUpEnabled(<span class="literal">true</span>)</span><br><span class="line"> it.setHomeAsUpIndicator(R.drawable.ic_baseline_dehaze_24)</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"><span class="comment">// 实现滑动菜单栏菜单选项的点击事件</span></span><br><span class="line"> binding.navView.setNavigationItemSelectedListener {</span><br><span class="line"> <span class="keyword">when</span> (it.itemId) {</span><br><span class="line"> R.id.myAppAndGames -> Toast.makeText(</span><br><span class="line"> <span class="keyword">this</span>,</span><br><span class="line"> <span class="string">"You clicked My app & games"</span>,</span><br><span class="line"> Toast.LENGTH_SHORT</span><br><span class="line"> ).show()</span><br><span class="line"> R.id.notification -> Toast.makeText(</span><br><span class="line"> <span class="keyword">this</span>,</span><br><span class="line"> <span class="string">"You clicked Notification"</span>,</span><br><span class="line"> Toast.LENGTH_SHORT</span><br><span class="line"> ).show()</span><br><span class="line"> R.id.subscription -> Toast.makeText(</span><br><span class="line"> <span class="keyword">this</span>,</span><br><span class="line"> <span class="string">"You clicked Subscription"</span>,</span><br><span class="line"> Toast.LENGTH_SHORT</span><br><span class="line"> ).show()</span><br><span class="line"> R.id.wishList -> Toast.makeText(<span class="keyword">this</span>, <span class="string">"You clicked Wishlist"</span>, Toast.LENGTH_SHORT)</span><br><span class="line"> .show()</span><br><span class="line"> R.id.account -> Toast.makeText(<span class="keyword">this</span>, <span class="string">"You clicked Account"</span>, Toast.LENGTH_SHORT)</span><br><span class="line"> .show()</span><br><span class="line"> R.id.paymentMethods -> Toast.makeText(</span><br><span class="line"> <span class="keyword">this</span>,</span><br><span class="line"> <span class="string">"You clicked Payment methods"</span>,</span><br><span class="line"> Toast.LENGTH_SHORT</span><br><span class="line"> ).show()</span><br><span class="line"> R.id.playProtect -> Toast.makeText(</span><br><span class="line"> <span class="keyword">this</span>,</span><br><span class="line"> <span class="string">"You clicked Play protect"</span>,</span><br><span class="line"> Toast.LENGTH_SHORT</span><br><span class="line"> ).show()</span><br><span class="line"> R.id.settings -> Toast.makeText(<span class="keyword">this</span>, <span class="string">"You clicked Settings"</span>, Toast.LENGTH_SHORT)</span><br><span class="line"> .show()</span><br><span class="line"> <span class="keyword">else</span> -> Log.d(</span><br><span class="line"> <span class="string">"MainActivity"</span>,</span><br><span class="line"> <span class="string">"There still has some items of navigationView don't config!"</span></span><br><span class="line"> )</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 注意最后需要一个返回值,返回 true 表明操作逻辑已完成</span></span><br><span class="line"> <span class="comment">// 实现点击某个选项后隐藏滑动菜单栏</span></span><br><span class="line"> binding.drawerLayout.closeDrawers()</span><br><span class="line"> <span class="literal">true</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="效果"><a href="#效果" class="headerlink" title="效果"></a>效果</h2><p><img src="E:\github\hexo\source\images\Screenshot_1624669444.png" style="zoom:20%;" /><img src="E:\github\hexo\source\images\Screenshot_1624670029.png" style="zoom:20%;" /><img src="E:\github\hexo\source\images\Screenshot_1624669549.png" style="zoom:20%;" /></p><p>参考:</p><p><a href="https://developer.android.google.cn/topic/libraries/view-binding">视图绑定 | Android 开发者 | Android Developers (google.cn)</a></p><p>郭霖. 第一行代码 Android[M]. 第三版. 北京: 人民邮电出版社. 2020. 483-491.</p>]]></content>
<tags>
<tag> Android </tag>
</tags>
</entry>
<entry>
<title>Android 模拟器访问开发计算机本地主机上的内容</title>
<link href="/2021/06/24/Android-%E6%A8%A1%E6%8B%9F%E5%99%A8%E8%AE%BF%E9%97%AE%E5%BC%80%E5%8F%91%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%9C%AC%E5%9C%B0%E4%B8%BB%E6%9C%BA%E4%B8%8A%E7%9A%84%E5%86%85%E5%AE%B9/"/>
<url>/2021/06/24/Android-%E6%A8%A1%E6%8B%9F%E5%99%A8%E8%AE%BF%E9%97%AE%E5%BC%80%E5%8F%91%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%9C%AC%E5%9C%B0%E4%B8%BB%E6%9C%BA%E4%B8%8A%E7%9A%84%E5%86%85%E5%AE%B9/</url>
<content type="html"><![CDATA[<h2 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h2><p>在学习郭霖的《第一行代码 Android 第三版》11.3节使用<code>OkHttp</code>解析本地主机上的<code>get_data.xml</code>文件,对代码(关键代码如下)中的 ip 地址产生的疑惑。</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> client = OkHttpClient()</span><br><span class="line"><span class="keyword">val</span> request = Request.Builder().url(<span class="string">"http://10.0.2.2/get_data.xml"</span>).build()</span><br></pre></td></tr></table></figure><p>在书写时写为:</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> client = OkHttpClient()</span><br><span class="line"><span class="keyword">val</span> request = Request.Builder().url(<span class="string">"http://127.0.0.1/get_data.xml"</span>).build()</span><br></pre></td></tr></table></figure><p>运行时发现给出以下报错信息:</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><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">W/System.err: java.net.ConnectException: Failed to connect to /<span class="number">127.0</span><span class="number">.0</span><span class="number">.1</span>:<span class="number">80</span></span><br><span class="line">.</span><br><span class="line">.</span><br><span class="line">W/System.err: at okhttp3.<span class="keyword">internal</span>.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:<span class="number">106</span>)</span><br><span class="line">.</span><br><span class="line">.</span><br><span class="line">W/System.err: at okhttp3.<span class="keyword">internal</span>.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:<span class="number">109</span>)</span><br><span class="line">.</span><br><span class="line">.</span><br><span class="line">W/System.err: at okhttp3.<span class="keyword">internal</span>.connection.RealCall.execute(RealCall.kt:<span class="number">154</span>)</span><br><span class="line">.</span><br><span class="line">.W/System.err: at kotlin.concurrent.ThreadsKt$thread$thread$<span class="number">1.</span>run(Thread.kt:<span class="number">30</span>)</span><br><span class="line"> Caused <span class="keyword">by</span>: java.net.ConnectException: failed to connect to /<span class="number">127.0</span><span class="number">.0</span><span class="number">.1</span> (port <span class="number">80</span>) from /<span class="number">127.0</span><span class="number">.0</span><span class="number">.1</span> (port <span class="number">50104</span>) after 10000ms: isConnected failed: ECONNREFUSED (Connection refused)</span><br><span class="line">.</span><br><span class="line">.</span><br><span class="line">W/System.err: at okhttp3.<span class="keyword">internal</span>.platform.Platform.connectSocket(Platform.kt:<span class="number">120</span>)</span><br><span class="line"> at okhttp3.<span class="keyword">internal</span>.connection.RealConnection.connectSocket(RealConnection.kt:<span class="number">295</span>)</span><br><span class="line"> ... <span class="number">18</span> more</span><br><span class="line"> Caused <span class="keyword">by</span>: android.system.ErrnoException: isConnected failed: ECONNREFUSED (Connection refused)</span><br><span class="line">W/System.err: at libcore.io.IoBridge.isConnected(IoBridge.java:<span class="number">274</span>)</span><br><span class="line"> ... <span class="number">28</span> more</span><br></pre></td></tr></table></figure><p>关键之处便在于将 ip 地址从<code>10.0.2.2</code>改为<code>127.0.0.1</code>,从而产生报错。</p><h2 id="解决方法"><a href="#解决方法" class="headerlink" title="解决方法"></a>解决方法</h2><p>经查阅相关资料发现,模拟器的每个实例都在<strong>虚拟路由器/防火墙服务</strong>后面运行,这样便将其与开发计算机网络接口和设置以及互联网隔离开来。<code>模拟设备</code><strong>无法</strong>在网络上看到<code>开发计算机</code>或<code>其他模拟器</code>实例,而只会看到它通过以太网连接到路由器/防火墙。每个实例的虚拟路由器管理是<code>10.0.2.x/24</code>,其中<code>x</code>可变。</p><p>具体的一些 ip 地址与对应说明如下表:</p><table><thead><tr><th>网络地址</th><th>说明</th></tr></thead><tbody><tr><td>10.0.2.1</td><td>路由器/网关地址</td></tr><tr><td>10.0.2.2</td><td><strong>主机回环接口</strong>的特殊别名(即,开发计算机上的 127.0.0.1)</td></tr><tr><td>10.0.2.3</td><td>第一个 DNS 服务器</td></tr><tr><td>10.0.2.4 / 10.0.2.5 / 10.0.2.6</td><td>可选的第二个、第三个和第四个 DNS 服务器(如果有)</td></tr><tr><td>10.0.2.15</td><td><strong>模拟设备</strong>网络/以太网接口</td></tr><tr><td>127.0.0.1</td><td><strong>模拟设备</strong>回环接口</td></tr></tbody></table><p>从表中可以看出,使用<code>127.0.0.1</code>实际上对应的是<strong>模拟器</strong>本身的回环接口,要想访问<strong>开发计算机</strong>的<code>127.0.0.1</code>上的内容,需要使用<code>10.0.2.2</code>进行相关的访问。</p><p>此外,<strong>模拟设备</strong>的预分配地址是 Android <strong>模拟器专用</strong>的地址,并且在<strong>真实设备</strong>上可能截然不同(它们也很可能是经过 NAT 处理的地址,具体来说,就是路由器/防火墙后面的地址)。</p><p>参考:</p><p><a href="https://developer.android.google.cn/studio/run/emulator-networking?hl=zh-cn">设置 Android 模拟器网络 | Android 开发者 | Android Developers (google.cn)</a></p>]]></content>
<tags>
<tag> Android </tag>
</tags>
</entry>
<entry>
<title>java 的环境变量配置</title>
<link href="/2021/06/24/java-%E7%9A%84%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%E9%85%8D%E7%BD%AE/"/>
<url>/2021/06/24/java-%E7%9A%84%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%E9%85%8D%E7%BD%AE/</url>
<content type="html"><![CDATA[<p>Java 的环境变量配置过程如下:</p><ul><li><p>下载 jdk 包,本文下载的版本为<code>jdk 11.0.11</code>的压缩包(<code>jdk-11.0.11_windows-x64_bin.zip)</code>),下载地址:<a href="https://www.oracle.com/java/technologies/javase-jdk11-downloads.html">Java SE Development Kit 11- - Downloads (oracle.com)</a>。</p></li><li><p>将下载好的压缩包解压至某个盘符的的某个文件夹下(路径最好不要出现中文),如本文解压至:<code>D:\JDK。</code></p></li><li><p>在Windows徽标上右击选择<strong>系统</strong>,向下翻点击<strong>高级系统设置</strong>,继续点击<strong>环境变量</strong>,在下面的<strong>系统变量</strong>中进行相应的设置。</p><ul><li>点击新建,变量名设为<code>JAVA_HIOME</code>,变量值为 jdk 解压缩之后的文件夹内,如本文的为:<code>D:\JDK\jdk-11.0.11</code>,点击确定。</li><li>双击<code>Path</code>,点击新建,输入的内容为:<code>%JAVA_HOME%\bin</code>,然后将其上移至第一个。</li></ul></li><li><p>验证是否环境变量设置完成,在 jdk 解压缩的盘符内的任意一个文件夹打开 cmd ,输入<code>java -version</code>,若出现版本信息则表示配置成功。</p></li></ul><p>参考:</p><p><a href="https://www.liaoxuefeng.com/wiki/1252599548343744/1280507291631649">安装JDK - 廖雪峰的官方网站 (liaoxuefeng.com)</a></p>]]></content>
<tags>
<tag> Java </tag>
</tags>
</entry>
<entry>
<title>Android 模拟器访问本地主机的 ip 地址问题</title>
<link href="/2021/06/23/Android-%E6%A8%A1%E6%8B%9F%E5%99%A8%E8%AE%BF%E9%97%AE%E6%9C%AC%E5%9C%B0%E4%B8%BB%E6%9C%BA%E7%9A%84-ip-%E5%9C%B0%E5%9D%80%E9%97%AE%E9%A2%98/"/>
<url>/2021/06/23/Android-%E6%A8%A1%E6%8B%9F%E5%99%A8%E8%AE%BF%E9%97%AE%E6%9C%AC%E5%9C%B0%E4%B8%BB%E6%9C%BA%E7%9A%84-ip-%E5%9C%B0%E5%9D%80%E9%97%AE%E9%A2%98/</url>
<content type="html"><![CDATA[<p>[TOC]</p><h2 id="文章背景"><a href="#文章背景" class="headerlink" title="文章背景"></a>文章背景</h2><p>在学习 Android 的网络通信中的 Okhttp 时,使用模拟器解析<code>本地主机上</code> 回环地址<code>127.0.0.1</code>上的 get_data.xml 文件时,原文关键代码为:</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> client = OkHttpClient()</span><br><span class="line"><span class="keyword">val</span> request = Request.Builder().url(<span class="string">"http://10.0.2.2/get_data.xml"</span>).build()</span><br></pre></td></tr></table></figure><p>在练习时写为:</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> client = OkHttpClient()</span><br><span class="line"><span class="keyword">val</span> request = Request.Builder().url(<span class="string">"http://127.0.0.1/get_data.xml"</span>).build()</span><br></pre></td></tr></table></figure><p>在测试时发现提示初始化时提示错误,</p><h2 id="解决办法"><a href="#解决办法" class="headerlink" title="解决办法"></a>解决办法</h2><p>经查询资料发现在<code>模拟器</code>中测试解析 ip 地址为<code> 127.0.0.1</code> 实际上访问的为<code>模拟器</code>本身。要想访问开发计算机的本地主机地址<code>127.0.0.1</code> 上的内容时,需要将 ip 变为 <code>10.0.2.2</code>。</p>]]></content>
<tags>
<tag> Android </tag>
</tags>
</entry>
<entry>
<title>Android 使用 http 通信</title>
<link href="/2021/06/23/Android-%E4%BD%BF%E7%94%A8-http-%E9%80%9A%E4%BF%A1/"/>
<url>/2021/06/23/Android-%E4%BD%BF%E7%94%A8-http-%E9%80%9A%E4%BF%A1/</url>
<content type="html"><![CDATA[<p>背景:Android 9.0 之后,应用程序只允许使用 <code>https</code> 类型的网络请求,这是由于 http 存在<code>网络安全隐患</code>而默认不被支持,下面介绍如何支持使用 http。 </p><p>在res目录右击新建一个文件名为xml的文件夹($res \rightarrow New \rightarrow Directory \rightarrow xml$)</p><p>然后在xml中新建文件,文件名文件类型为:<code>network_config.xml</code>,文件内容如下,其含义为允许我们使用明文的方式在网络上进行传输数据。</p><figure class="highlight xml"><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></pre></td><td class="code"><pre><span class="line"><span class="meta"><?xml version="1.0" encoding="utf-8"?></span></span><br><span class="line"><span class="tag"><<span class="name">network-security-config</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">base-config</span> <span class="attr">cleartextTrafficPermitted</span>=<span class="string">"true"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">trust-anchors</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">certificates</span> <span class="attr">src</span>=<span class="string">"system"</span> /></span></span><br><span class="line"> <span class="tag"></<span class="name">trust-anchors</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">base-config</span>></span></span><br><span class="line"><span class="tag"></<span class="name">network-security-config</span>></span></span><br></pre></td></tr></table></figure><p>然后修改<code>AndroidManifest.xml</code>中的代码以启用上述配置,添加内容为:<code>android:networkSecurityConfig="@xml/network_config"。</code>添加位置如下:</p><figure class="highlight xml"><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><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">.</span><br><span class="line">.</span><br><span class="line"><span class="tag"><<span class="name">application</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:allowBackup</span>=<span class="string">"true"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">.</span></span></span><br><span class="line"><span class="tag"> <span class="attr">.</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:networkSecurityConfig</span>=<span class="string">"@xml/network_config ></span></span></span><br><span class="line"><span class="string"><span class="tag"> .</span></span></span><br><span class="line"><span class="string"><span class="tag"> .</span></span></span><br><span class="line"><span class="string"><span class="tag"></application></span></span></span><br></pre></td></tr></table></figure><p>参考:</p><p>郭霖. 第一行代码 Android[M]. 第三版. 北京: 人民邮电出版社. 2020. 440-441.</p>]]></content>
<tags>
<tag> Android </tag>
</tags>
</entry>
<entry>
<title>Hello World</title>
<link href="/2021/06/23/hello-world/"/>
<url>/2021/06/23/hello-world/</url>
<content type="html"><![CDATA[<p>Welcome to <a href="https://hexo.io/">Hexo</a>! This is your very first post. Check <a href="https://hexo.io/docs/">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a href="https://hexo.io/docs/troubleshooting.html">troubleshooting</a> or you can ask me on <a href="https://github.com/hexojs/hexo/issues">GitHub</a>.</p><h2 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h2><h3 id="Create-a-new-post"><a href="#Create-a-new-post" class="headerlink" title="Create a new post"></a>Create a new post</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo new <span class="string">"My New Post"</span></span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/writing.html">Writing</a></p><h3 id="Run-server"><a href="#Run-server" class="headerlink" title="Run server"></a>Run server</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo server</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/server.html">Server</a></p><h3 id="Generate-static-files"><a href="#Generate-static-files" class="headerlink" title="Generate static files"></a>Generate static files</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo generate</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/generating.html">Generating</a></p><h3 id="Deploy-to-remote-sites"><a href="#Deploy-to-remote-sites" class="headerlink" title="Deploy to remote sites"></a>Deploy to remote sites</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo deploy</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/one-command-deployment.html">Deployment</a></p>]]></content>
</entry>
</search>