游泳天花板 發表於 2019-10-13 18:43:00

Xamarin.Android开发

<p>使用 Visual Studio 生成第一个 Xamarin.Android 应用程序,并进一步了解使用 Xamarin 进行 Android 应用程序开发的基础知识。在此过程中,会介绍生成和部署 Xamarin.Android 应用程序所需的工具、概念和步骤。</p>
<p>链接</p>
<h2 id="part-1-quickstartandroidget-startedhello-androidhello-android-quickstartmd">第 1 部分:快速入门</h2>
<p><span data-ttu-id="9e5bf-107">在本指南的第一部分,用户将创建一个应用程序,该应用程序可将用户输入的字母数字电话号码转换为数字电话号码,然后呼叫该号码。</span></p>
<h2 id="part-2-deep-diveandroidget-startedhello-androidhello-android-deepdivemd">第 2 部分:深入了解</h2>
<p><span data-ttu-id="9e5bf-109">在本文档的第二部分,将回顾生成的应用程序,并从根本上了解 Android 应用程序的工作原理。</span></p>
<p><span data-ttu-id="b5b56-149">查看项目中的项,查看每个文件夹及其用途:</span></p>
<ul>
<li>
<p><span data-ttu-id="b5b56-150">Properties&nbsp;– 包含&nbsp;AndroidManifest.xml&nbsp;文件,该文件描述了对 Xamarin.Android 应用程序的所有要求(包括名称、版本号和权限),此外<span data-ttu-id="b5b56-151">还包括.NET 程序集元数据文件&nbsp;AssemblyInfo.cs,可以<span data-ttu-id="b5b56-152">在此文件中填写一些应用程序相关的基本信息。</span></span></span></p>
</li>
<li>
<p><span data-ttu-id="b5b56-153">引用&nbsp;– 包含生成和运行应用程序所需的程序集。<span data-ttu-id="b5b56-154">如果展开“引用”目录,可查看对 .NET 程序集(如&nbsp;System、System.Core 和&nbsp;System.Xml)的引用以及对 Xamarin 的 Mono.Android 程序集的引用。</span></span></p>
</li>
<li>
<p><span data-ttu-id="b5b56-155">Assets – 包含应用程序需要运行的文件(包括字体、本地数据文件和文本文件)。<span data-ttu-id="b5b56-156">此处包括的文件可通过生成的&nbsp;<code>Assets</code>&nbsp;类访问。<span data-ttu-id="b5b56-157">有关 Android 资产的详细信息,请参阅 Xamarin&nbsp;使用 Android 资产指南。</span></span></span></p>
</li>
<li>
<p><span data-ttu-id="b5b56-158">Resources – 包含应用程序资源,例如字符串、图像和布局。<span data-ttu-id="b5b56-159">可以通过生成的&nbsp;<code>Resource</code>&nbsp;类访问代码中的这些资源。&nbsp;<span data-ttu-id="b5b56-160">Android 资源指南提供有关“资源” 目录的更多详细信息。&nbsp;<span data-ttu-id="b5b56-161">应用程序模板在&nbsp;AboutResources.txt&nbsp;文件中还包含有“资源”的简明指南。</span></span></span></span></p>
</li>
</ul>
<h3 id="resources"><span data-ttu-id="b5b56-162">1、资源</span></h3>
<p><span data-ttu-id="b5b56-163">“资源”目录包含 4 类文件夹(drawable、layout、mipmap 和 values),还有一个名为 Resource.designer.cs 的文件 。</span></p>
<ul>
<li>
<p><span data-ttu-id="b5b56-165">drawable&nbsp;– 可绘制目录包含可绘制资源,如图像和位图。</span></p>
</li>
<li>
<p><span data-ttu-id="b5b56-166">mipmap&nbsp;– mipmap 目录包含适用于不同启动器图标密度的可绘制文件。&nbsp;<span data-ttu-id="b5b56-167">在默认模板中,drawable 目录包含应用程序图标文件“Icon.png” 。</span></span></p>
</li>
</ul>
<div class="zone has-pivot" data-pivot="windows">
<ul>
<li><span data-ttu-id="b5b56-168">layout&nbsp;– 布局目录包含<span style="color: rgba(255, 0, 0, 1)">&nbsp;<em>Android 设计器文件</em>&nbsp;(.axml),该文件定义每个屏幕或活动的用户界面</span>。&nbsp;<span data-ttu-id="b5b56-169">该模板创建名为 activity_main.axml 的默认布局 。</span></span></li>
</ul>
</div>
<ul>
<li>
<p><span data-ttu-id="b5b56-172">values&nbsp;– 此目录包含存储简单值(如字符串、整数和颜色)的 XML 文件。&nbsp;<span data-ttu-id="b5b56-173">该模板创建名为&nbsp;Strings.xml&nbsp;的文件,用于存储字符串值。</span></span></p>
</li>
</ul>
<p><span data-ttu-id="b5b56-172"><span data-ttu-id="b5b56-173">  代码中使用:</span></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">string</span> info = <span style="color: rgba(0, 0, 255, 1)">this</span>.Resources.GetString(Resource.String.button_bundle_info);</pre>
</div>
<ul>
<li>
<p><span data-ttu-id="b5b56-174">Resource.designer.cs&nbsp;– 也称为&nbsp;<code>Resource</code>&nbsp;类,此文件是一个分部类,存放分配给每个资源的唯一 ID。<span data-ttu-id="b5b56-175">它由 Xamarin.Android 工具自动创建,并在必要时重新生成。<span data-ttu-id="b5b56-176"><span style="color: rgba(255, 0, 0, 1)">不应手动编辑此文件</span>,因为 Xamarin.Android 将覆盖对其进行的任何手动更改。</span></span></span></p>
</li>
</ul>
<p><span data-ttu-id="b5b56-174"><span data-ttu-id="b5b56-175"><span data-ttu-id="b5b56-176">更多查看:Android资源</span></span></span></p>
<h3 id="app-fundamentals-and-architecture-basics"><span data-ttu-id="b5b56-177">2、应用基础知识和体系结构基础知识</span></h3>
<p><span data-ttu-id="b5b56-178">Android应用程序不具有单一入口点;也就是说,应用程序中没有操作系统可调用来启动该应用程序的任何代码行。<span data-ttu-id="b5b56-179">相反,当 Android 实例化应用程序的一个类时,会启动该应用程序,在此期间Android 将整个应用程序的进程加载到内存中。</span></span></p>
<p><span data-ttu-id="b5b56-180">设计复杂应用程序或与 Android 操作系统交互时,Android 的这一特有功能极其有用。&nbsp;<span data-ttu-id="b5b56-181">但是,这些选项也使 Android 在处理&nbsp;Phoneword&nbsp;应用程序等基本方案时变得复杂。&nbsp;<span data-ttu-id="b5b56-182">出于此原因,分两种情况来探索 Android 体系结构。<span data-ttu-id="b5b56-183">本指南剖析使用 Android 应用最常见入口点(第一个屏幕)的应用程序。<span data-ttu-id="b5b56-184">在了解 Android 多屏幕中,讨论了以不同方式启动应用程序,全面探讨了 Android 体系结构的复杂性。</span></span></span></span></span></p>
<p><span data-ttu-id="b5b56-186">在仿真器或设备中首次打开&nbsp;Phoneword&nbsp;应用程序时,操作系统会创建第一个<em>Activity,<span style="color: rgba(255, 0, 0, 1)">Activity</span></em><span data-ttu-id="b5b56-187"><span style="color: rgba(255, 0, 0, 1)">是特殊的 Android 类,对应于单个应用程序屏幕,负责绘制和支持用户界面</span>。<span style="color: rgba(255, 0, 0, 1)">&nbsp;</span><span data-ttu-id="b5b56-188"><span style="color: rgba(255, 0, 0, 1)">Android 创建应用程序的第一个Activity时,会加载整个应用程序</span>:</span></span></span></p>
<p><span data-ttu-id="b5b56-189"><img src="https://docs.microsoft.com/zh-cn/xamarin/android/get-started/hello-android/hello-android-deepdive-images/01-activity-load-sml.png" alt="活动负载" data-linktype="relative-path"></span></p>
<p><span data-ttu-id="b5b56-190">由于 Android 应用程序中没有线性发展(可以通过多个点启动应用程序),Android 采用一种独特方式来跟踪哪些类和文件组成应用程序。&nbsp;<span data-ttu-id="b5b56-191">在&nbsp;Phoneword&nbsp;示例中,将向名为“<strong>Android Manifest</strong>” 的特殊 XML文件注册组成应用程序的所有部分。&nbsp;<span data-ttu-id="b5b56-192">“Android Manifest” 的作用是跟踪应用程序的内容、属性和权限,并将这些信息告知 Android 操作系统。&nbsp;<span data-ttu-id="b5b56-193">可以将&nbsp;Phoneword&nbsp;应用程序当作单一活动(屏幕)和由 Android 清单文件捆绑在一起的资源文件和帮助程序文件的集合,</span></span></span></span><span data-ttu-id="b5b56-193">如以下关系图所示:</span></p>
<p><span data-ttu-id="b5b56-194"><img src="https://docs.microsoft.com/zh-cn/xamarin/android/get-started/hello-android/hello-android-deepdive-images/02-resources-helpers-sml.png" alt="资源帮助程序" data-linktype="relative-path"></span></p>
<p><span data-ttu-id="b5b56-195">以下几个部分将探索&nbsp;Phoneword&nbsp;应用程序各部分的关系;使你能更好地理解上面的关系图。&nbsp;<span data-ttu-id="b5b56-196">此探索先从用户界面开始,会讨论 Android 设计器和布局文件。</span></span></p>
<h3 id="user-interface"><span data-ttu-id="b5b56-197">3、用户界面</span></h3>
<p><span data-ttu-id="b5b56-195"><span data-ttu-id="b5b56-196"><span data-ttu-id="b5b56-200"><span style="color: rgba(255, 0, 0, 1)">activity_main.axml 是应用程序中第一个屏幕的用户界面布局文件</span> 。&nbsp;<span data-ttu-id="b5b56-201">.axml 指示这是 Android 设计器文件(AXML 表示&nbsp;<em>Android XML,</em><span data-ttu-id="b5b56-202">名称 Main 对 Android 而言是任意的 – 可将布局文件命名为其他名称。<span data-ttu-id="b5b56-203">在IDE中打开activity_main.axml 时,会显示名为“Android Designer”的 Android 布局文件的可视编辑器 :</span></span></span></span></span></span></p>
<p><span data-ttu-id="b5b56-195"><span data-ttu-id="b5b56-196">TranslateButton&nbsp;的 ID 设置为&nbsp;<code>@+id/TranslateButton</code>:</span></span></p>
<p><span data-ttu-id="b5b56-195"><span data-ttu-id="b5b56-196"><span data-ttu-id="b5b56-214">设置&nbsp;TranslateButton&nbsp;的&nbsp;<code>id</code>&nbsp;属性时,Android Designer 会将&nbsp;TranslateButton&nbsp;控件映射到&nbsp;<code>Resource</code>&nbsp;类,并为其分配&nbsp;<code>TranslateButton</code>&nbsp;的资源 ID 。&nbsp;<span data-ttu-id="b5b56-215">通过将可视控件映射到类,可以找到并使用&nbsp;TranslateButton&nbsp;和应用代码中的其他控件。&nbsp;<span data-ttu-id="b5b56-216">当你剖析为控件提供支持的代码时,会更详细地了解这一内容。&nbsp;<span data-ttu-id="b5b56-217">此时,只需知道<span style="color: rgba(255, 0, 0, 1)">控件的代码表示形式是通过&nbsp;<code>id</code>&nbsp;属性链接到设计器中控件的可视表示形式即可</span>。</span></span></span></span></span></span></p>
<p><strong><span data-ttu-id="b5b56-218">源视图</span></strong></p>
<p><span data-ttu-id="b5b56-219">在设计界面上定义的所有内容都会转换成 XML,以供 Xamarin.Android 使用。&nbsp;<span data-ttu-id="b5b56-220">Android 设计器提供源视图,此源视图包含从可视化设计器生成的 XML,<span data-ttu-id="b5b56-221">可以切换到设计器视图左下角的“源” 面板以查看此 XML</span></span></span></p>
<h3 id="activities-and-the-activity-lifecycle"><span data-ttu-id="b5b56-228">4、Activities和活动生命周期</span></h3>
<p><span data-ttu-id="b5b56-229"><code>Activity</code>&nbsp;类包含为用户界面提供支持的代码,<span style="color: rgba(255, 0, 0, 1)">activity</span><span data-ttu-id="b5b56-230"><span style="color: rgba(255, 0, 0, 1)">负责响应用户交互,并创建动态用户体验</span>。</span></span></p>
<ul>
<li id="activity-class"><span data-ttu-id="b5b56-232">Activity 类</span></li>
</ul>
<p><span data-ttu-id="b5b56-233">Phoneword&nbsp;应用程序只有一个屏幕(活动)。<span data-ttu-id="b5b56-234">为屏幕提供支持的类称为<code>MainActivity</code>,位于MainActivity.cs&nbsp;文件中,<span data-ttu-id="b5b56-235">名称&nbsp;<code>MainActivity</code>&nbsp;在 Android 中没有特别的意义 – 虽然<span style="color: rgba(255, 0, 0, 1)">约定是命名应用程序&nbsp;<code>MainActivity</code>&nbsp;中的第一个活动</span>,但 Android 并不在意将其命名为其他名称。</span></span></span></p>
<p><span data-ttu-id="b5b56-233"><span data-ttu-id="b5b56-234"><span data-ttu-id="b5b56-235">打开&nbsp;MainActivity.cs&nbsp;时,可以看到,<code>MainActivity</code>&nbsp;类是&nbsp;<code>Activity</code>&nbsp;类的子类 并且活动标有&nbsp;Activity特性:</span></span></span><span data-ttu-id="b5b56-237"><span style="color: rgba(255, 0, 0, 1)">向 Android 清单注册Activity,这能让 Android 知道此类是该清单所管理的Phoneword&nbsp;应用程序的一部分</span>。</span></p>
<p><span data-ttu-id="b5b56-237"><span data-ttu-id="b5b56-238"><code>特性中:Label</code>&nbsp;属性设置将显示在屏幕顶部的文本【在values文件夹下的string.xml中管理】;</span></span><span data-ttu-id="b5b56-239"><span style="color: rgba(255, 0, 0, 1)"><code>MainLauncher</code>属性告知 Android 在启动应用程序时显示此活动</span>。&nbsp;<span data-ttu-id="b5b56-240">如了解 Android 多屏幕指南中所述,当你向应用程序添加更多活动(屏幕)时,此属性会变得很重要。</span></span></p>
<ul>
<li><strong><span data-ttu-id="b5b56-242">活动生命周期</span></strong></li>
</ul>
<p><span data-ttu-id="b5b56-243">在 Android 中,活动会根据与用户的交互经历生命周期的不同阶段。<span data-ttu-id="b5b56-244">可以对活动进行创建、启动和暂停、恢复和销毁等操作。<span data-ttu-id="b5b56-245"><code>Activity</code>&nbsp;类包含这些方法,系统会在屏幕生命周期的特定时间点调用这些方法。&nbsp;<span data-ttu-id="b5b56-246"><br></span></span></span></span></p>
<p><span data-ttu-id="b5b56-248"><span style="color: rgba(255, 0, 0, 1)">通过重写&nbsp;<code>Activity</code>&nbsp;生命周期方法,可以控制活动的加载方式和与用户的互动方式,甚至还可以控制活动从设备屏幕消失后会发生的情况</span>。&nbsp;<span data-ttu-id="b5b56-249">例如,可以重写生命周期方法,以执行以下重要任务:</span></span></p>
<ul>
<li>
<p><span data-ttu-id="b5b56-250">OnCreate&nbsp;– 创建视图、初始化变量,并执行在用户能看到活动之前其他必须完成的准备工作。<span data-ttu-id="b5b56-251">只有将活动加载到内存时,才会调用此方法一次。【向用户显示屏幕之前】</span></span></p>













</li>
<li>
<p><span data-ttu-id="b5b56-252">OnResume&nbsp;– 执行每当活动返回到设备屏幕时必须发生的任何任务。【从主屏幕再次回到app也会调用此方法】</span></p>













</li>
<li>
<p><span data-ttu-id="b5b56-253">OnPause&nbsp;– 执行每当活动离开设备屏幕时必须发生的任何任务。【单击home键,离开app时】</span></p>

</li>

</ul>
<p>在“<code>Activity</code>”中将自定义代码添加到生命周期方法时,您将覆盖该生命周期方法的基本实现。 您可以利用现有的生命周期方法(已附加一些代码),然后使用自己的代码扩展该方法。 您<span style="color: rgba(255, 0, 0, 1)">可以从方法内部调用基本实现,以确保原始代码(base.OnCreate())在新代码之前运行</span>。 下一部分将说明一个示例。</p>
<p>活动生命周期是Android的重要组成部分。 完成入门系列后,如果您想了解有关活动的更多信息,请阅读活动生命周期指南。&nbsp;</p>
<p><strong>OnCreate</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> OnCreate (Bundle bundle)
{
    </span><span style="color: rgba(0, 0, 255, 1)">base</span><span style="color: rgba(0, 0, 0, 1)">.OnCreate (bundle);

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Set our view from the "main" layout resource</span>
<span style="color: rgba(0, 0, 0, 1)">    SetContentView (Resource.Layout.activity_main);
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Additional setup code will go here</span>
}</pre>
</div>
<p>Bundle:从字符串值到各种可打包类型的映射</p>
<p><span data-ttu-id="b5b56-264">OnCreate中<span style="color: rgba(255, 0, 0, 1)">加载在 Android Designer中创建的用户界面:</span><span data-ttu-id="b5b56-265"><span style="color: rgba(255, 0, 0, 1)">请调用&nbsp;<code>SetContentView</code>&nbsp;并向其传递布局文件的资源布局名称:activity_main.axml</span>&nbsp;,<span data-ttu-id="b5b56-266">布局位于&nbsp;<code>Resource.Layout.activity_main</code></span></span></span></p>
<div class="zone has-pivot" data-pivot="windows">
<p><span data-ttu-id="b5b56-267">当&nbsp;<code>MainActivity</code>&nbsp;开始运行后,会基于 activity_main.axml 文件的内容创建一个视图 。</span></p>
</div>
<p><span data-ttu-id="b5b56-274">准备好布局文件后,可以开始查找控件,<span data-ttu-id="b5b56-275">若要查找控件,请调用&nbsp;<code>FindViewById</code>,并传入控件的资源 ID。</span></span></p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Get our UI controls from the loaded layout</span>
            EditText phoneNumberText = FindViewById&lt;EditText&gt;<span style="color: rgba(0, 0, 0, 1)">(Resource.Id.PhoneNumberText);
            TextView translatedPhoneWord </span>= FindViewById&lt;TextView&gt;<span style="color: rgba(0, 0, 0, 1)">(Resource.Id.TranslatedPhoneword);
            Button translateButton </span>= FindViewById&lt;Button&gt;(Resource.Id.TranslateButton);</pre>
</div>
<p><span data-ttu-id="b5b56-274"><span data-ttu-id="b5b56-275">现在布局文件中已具有对控件的引用,可以开始对其进行编程,以响应用户交互。</span></span></p>
<p id="responding-to-user-interaction"><strong><span data-ttu-id="b5b56-277">响应用户交互</span></strong></p>
<p><span data-ttu-id="b5b56-278">在 Android 中,&nbsp;<code>Click</code>&nbsp;事件侦听用户的触控,<span data-ttu-id="b5b56-279">在此应用中,<code>Click</code>&nbsp;事件将由 lambda 处理,不过也可改用委托或命名事件处理程序。</span></span></p>
<div class="cnblogs_code">
<pre>translateButton.Click += (sender, e) =&gt;<span style="color: rgba(0, 0, 0, 1)">
            {
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Translate user's alphanumeric phone number to numeric</span>
                <span style="color: rgba(0, 0, 255, 1)">string</span> translatedNumber =<span style="color: rgba(0, 0, 0, 1)"> PhoneTranslator.ToNumber(phoneNumberText.Text);
                </span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">.IsNullOrWhiteSpace(translatedNumber))
                {
                  translatedPhoneWord.Text </span>= <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">.Empty;
                }
                </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
                {
                  translatedPhoneWord.Text </span>=<span style="color: rgba(0, 0, 0, 1)"> translatedNumber;
                }
            };</span></pre>
</div>
<h3 id="set-icons-for-different-screen-densities"><strong><span data-ttu-id="b5b56-298">5、为不同的屏幕密度设置图标</span></strong></h3>
<p><span data-ttu-id="b5b56-299">Android 设备具有不同的屏幕大小和分辨率,不是所有图像都能清晰显示在屏幕上。</span></p>
<p><span data-ttu-id="b5b56-299"><span data-ttu-id="b5b56-303">考虑到这一点,最好将不同分辨率的图标添加到&nbsp;Resources文件夹。&nbsp;<span data-ttu-id="b5b56-304">Android 提供了不同版本的 mipmap 文件夹来处理不同密度的启动器图标,包括:</span></span></span></p>
<p><span data-ttu-id="b5b56-299"><span data-ttu-id="b5b56-303"><span data-ttu-id="b5b56-304"><span style="color: rgba(255, 0, 0, 1)">针对中等密度屏幕的 mdpi、针对高密度屏幕的 hdpi,以及针对超高密度屏幕的 xhdpi、xxhdpi 和 xxxhdpi</span> 。&nbsp;<span data-ttu-id="b5b56-305">不同大小的图标存储在相应的 mipmap- 文件夹中 。</span></span></span></span></p>
<p><span data-ttu-id="b5b56-299"><span data-ttu-id="b5b56-303"><span data-ttu-id="b5b56-304"><span data-ttu-id="b5b56-305">各文件夹下:</span></span></span></span></p>
<p><span data-ttu-id="b5b56-299"><span data-ttu-id="b5b56-303"><span data-ttu-id="b5b56-304"><span data-ttu-id="b5b56-305">ic_launcher:桌面图标【可以在设置-&gt;更多-&gt;应用程序中查看】,</span></span></span></span></p>
<p><span data-ttu-id="b5b56-299"><span data-ttu-id="b5b56-303"><span data-ttu-id="b5b56-304"><span data-ttu-id="b5b56-305">ic_launcher_background:背景图,</span></span></span></span></p>
<p><span data-ttu-id="b5b56-299"><span data-ttu-id="b5b56-303"><span data-ttu-id="b5b56-304"><span data-ttu-id="b5b56-305">ic_launcher_foreground:前景图,</span></span></span></span></p>
<p><span data-ttu-id="b5b56-299"><span data-ttu-id="b5b56-303"><span data-ttu-id="b5b56-304"><span data-ttu-id="b5b56-305">ic_launcher_round:圆形图【屏幕上的】,</span></span></span></span></p>
<p><span data-ttu-id="b5b56-311">并非每个人都具有可用于创建自定义图标和启动图像(让应用与众不同)的设计器。下面是几种生成自定义应用图像的备选方法:</span></p>
<div class="zone has-pivot" data-pivot="windows">
<ul>
<li>
<p><span data-ttu-id="b5b56-312">Android Asset Studio&nbsp;– 是一个基于 Web 的浏览器生成器,针对所有类型 Android 图标,带有其他有用社区工具的链接。&nbsp;<span data-ttu-id="b5b56-313">在 Google Chrome 中性能最佳。</span></span></p>
</li>
<li>
<p><span data-ttu-id="b5b56-314">Visual Studio – 可以用于直接在 IDE 中为应用创建简单图标集。</span></p>
</li>
<li>
<p><span data-ttu-id="b5b56-315">Glyphish&nbsp;– 可免费下载和购买的高质量预生成图标集。</span></p>
</li>
<li>
<p><span data-ttu-id="b5b56-316">Fiverr&nbsp;– 从各种设计器中进行选择以便为你创建图标集(最低 5 美元)。&nbsp;<span data-ttu-id="b5b56-317">可以漫无目标,不过如果需要动态设计的图标,这是很好的资源。</span></span></p>
</li>
</ul>
</div>
<p><span data-ttu-id="b5b56-328">有关图标大小和要求的详细信息,请参阅&nbsp;Android 资源指南。</span></p>
<h2>应用程序基础知识</h2>
<p><strong>可访问性</strong></p>
<p><strong>API级别</strong></p>
<h3><strong>1、Android资源</strong></h3>
<p><img src="https://img2018.cnblogs.com/blog/727485/201909/727485-20190917172510113-1913664902.png" alt=""></p>
<p>新增加资源:eg,my_image_name .png【约定用下划线,小写】,并将其生成操作设置为:Android资源</p>
<h3 id="activity-lifecycle-methods"><strong><span data-ttu-id="06b73-151">2、活动生命周期方法</span></strong></h3>
<p><span style="color: rgba(255, 0, 0, 1)" data-ttu-id="06b73-151">一个Activity活动就是一个界面的布局。</span>参考:onResume什么时候执行,执行几次的问题</p>
<p>程序正常启动时:onCreate()-&gt;onStart()-&gt;onResume();<br>onCreate()在活动第一次创建时被调用,主要用于加载布局。<br>onStart()这个方法在活动由不可见变为可见的时候调用。<br>onResume()这个方法在活动准备好和用户进行交互的时候调用。此时的活动一定位于返回栈的栈顶,并且处于运行状态。</p>
<p><img src="https://img2018.cnblogs.com/blog/727485/201909/727485-20190918092739547-276618360.png" alt=""></p>
<p>三种调用的场景:<br>一个Activity启动另一个Activity: onPause()-&gt;onStop(),&nbsp; &nbsp; 再返回:onRestart()-&gt;onStart()-&gt;onResume()<br>程序按back 退出: onPause()-&gt;onStop()-&gt;<span style="color: rgba(255, 0, 0, 1)">onDestory</span>(),再进入:<span style="color: rgba(255, 0, 0, 1)">onCreate</span>()-&gt;onStart()-&gt;onResume();<br>程序按home 退出: onPause()-&gt;onStop(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 再进入:onRestart()-&gt;onStart()-&gt;onResume();</p>
<h4 id="oncreate"><span data-ttu-id="06b73-160">OnCreate</span></h4>
<p><span data-ttu-id="06b73-161">OnCreate是创建活动时要调用的第一个方法,<span data-ttu-id="06b73-162"><span style="color: rgba(255, 0, 0, 1)"><code>OnCreate</code>始终需要重写</span>,以执行活动可能需要的任何启动初始化,如:</span></span></p>
<ul>
<li><span data-ttu-id="06b73-163">创建视图</span></li>
<li><span data-ttu-id="06b73-164">初始化变量</span></li>
<li><span data-ttu-id="06b73-165">将静态数据绑定到列表</span></li>










</ul>
<p><span data-ttu-id="06b73-166"><code>OnCreate</code>采用一个绑定参数,该参数是在绑定不为 null 时<span style="color: rgba(255, 0, 0, 1)">用于存储和传递状态信息和活动之间的对象的字典</span>,这表示活动正在重新启动,应从上一个实例还原其状态。</span></p>
<h4 id="onstart"><span data-ttu-id="06b73-169">OnStart</span></h4>
<p><span data-ttu-id="06b73-170"><span style="color: rgba(255, 0, 0, 1)"><code>OnCreate</code>&nbsp;完成后 , 系统始终会调用&nbsp;<span style="color: rgba(255, 0, 0, 1)">OnStart</span></span>。&nbsp;<span data-ttu-id="06b73-171">如果活动在活动可见之前需要执行任何特定的任务,例如刷新活动中视图的当前值,则活动可能会重写此方法,<span style="color: rgba(255, 0, 0, 1)">调用此方法之后</span><span data-ttu-id="06b73-172"><span style="color: rgba(255, 0, 0, 1)">Android 将立即调用<code>OnResume</code></span>。</span></span></span></p>
<h4 id="onresume"><span data-ttu-id="06b73-173">OnResume</span></h4>
<p><span data-ttu-id="06b73-174">当活动准备好开始与用户交互时,系统将调用OnResume&nbsp;【Activity 开始跟用户交互之前会调用 onResume()】。&nbsp;<span data-ttu-id="06b73-175">活动应重写此方法以执行如下任务:</span></span></p>
<ul>
<li><span data-ttu-id="06b73-176">斜向上帧速率(游戏开发中的常见任务)</span></li>
<li><span data-ttu-id="06b73-177">开始动画</span></li>
<li><span data-ttu-id="06b73-178">侦听 GPS 更新</span></li>
<li><span data-ttu-id="06b73-179">显示任何相关的警报或对话框</span></li>
<li><span data-ttu-id="06b73-180">连接外部事件处理程序</span></li>

</ul>
<h4 id="onpause"><span data-ttu-id="06b73-183">OnPause</span></h4>
<p><span data-ttu-id="06b73-184">当系统要将活动放入背景中或活动被部分遮盖时,将调用OnPause&nbsp;。&nbsp;<span data-ttu-id="06b73-185">如果活动需要,则应重写此方法:</span></span></p>
<ul>
<li>
<p><span data-ttu-id="06b73-186">提交永久性数据的未保存更改</span></p>










</li>
<li>
<p><span data-ttu-id="06b73-187">销毁或清理使用资源的其他对象</span></p>










</li>
<li>
<p><span data-ttu-id="06b73-188">增加帧速率和暂停动画</span></p>










</li>
<li>
<p><span data-ttu-id="06b73-189">注销外部事件处理程序或通知处理程序(即绑定到服务的程序)。&nbsp;<span data-ttu-id="06b73-190">必须执行此操作以防止活动内存泄露。</span></span></p>










</li>
<li>
<p><span data-ttu-id="06b73-191">同样,如果活动显示了任何对话框或警报,则必须用<code>.Dismiss()</code>方法对其进行清理。</span></p>










</li>










</ul>
<p>在调用OnPause后,可能会调用以下两个方法:</p>
<p>1、OnResume:if the Activity is to be returned to the foreground.</p>
<p>2、OnStop:if the Activity is being placed in the background</p>
<h4 id="onstop"><span data-ttu-id="06b73-196">OnStop</span></h4>
<p><span data-ttu-id="06b73-197">当用户不再显示该活动时,将调用OnStop&nbsp;。&nbsp;<span data-ttu-id="06b73-198">发生以下情况之一时,会发生这种情况:</span></span></p>
<ul>
<li><span data-ttu-id="06b73-199">正在启动新活动,并覆盖此活动。</span></li>
<li><span data-ttu-id="06b73-200">现有活动将进入前台。</span></li>
<li><span data-ttu-id="06b73-201">正在销毁活动。</span></li>










</ul>
<h4 id="ondestroy"><span data-ttu-id="06b73-205">OnDestroy</span></h4>
<p><span data-ttu-id="06b73-206">OnDestroy是在将其销毁并从内存中完全删除之前,在活动实例上调用的最终方法。</span></p>
<p><span data-ttu-id="06b73-206">大多数活动将不会实现此方法,因为大多数清理和关闭操作都是通过OnPause和OnStop方法完成的;</span><span data-ttu-id="06b73-206">而需要重写OnDestroy方法一般是用来清理长时间运行的可能会泄漏的资源,例如 在OnCreate中启动的后台线程。</span></p>
<p><strong>OnRestart</strong></p>
<p>对于应该在OnRestart中实现哪种逻辑,没有通用的指导原则。这是因为无论正在创建活动还是重新启动活动,都始终调用OnStart,因此活动所需的任何资源都应该在OnStart中初始化,而不是在OnRestart中初始化。</p>
<h3 id="back-vs-home"><span class="sxs-lookup">3、Back vs. Home</span></h3>
<p>程序按back 退出: onPause()-&gt;onStop()-&gt;<span style="color: rgba(255, 0, 0, 1)">onDestory()</span>,再进入:onCreate()-&gt;onStart()-&gt;onResume();<br>程序按home 退出: onPause()-&gt;onStop(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 再进入:onRestart()-&gt;onStart()-&gt;onResume();</p>
<p>按Back键会销毁程序,home不会,只是退到后台线程。</p>
<h3 id="managing-state-throughout-the-lifecycle"><span class="sxs-lookup">4、Managing State Throughout the Lifecycle</span></h3>
<p>在停止或者销毁时,系统提供一种保存状态(实例状态)的机会,三种方式:</p>
<ul>
<li>android采用称之为<span style="color: rgba(255, 0, 0, 1)">Bundle</span>的字典(key/value) 来保存原始值</li>
<li>Creating a custom class that will hold complex values such as bitmaps.</li>
<li>绕过配置更改生命周期,并承担维护活动状态的全部责任。</li>







</ul>
<p><strong>4.1、Bundle介绍</strong></p>
<p>Bundle不适合保存复杂数据(如 位图)</p>
<p><span data-ttu-id="06b73-241">活动提供一些方法来帮助在捆绑包中保存和检索实例状态:</span></p>
<ul>
<li>
<p><span data-ttu-id="06b73-242">OnSaveInstanceState–此操作由 Android 在活动被销毁时调用。&nbsp;<span data-ttu-id="06b73-243">如果活动需要保留任何键/值状态项,则这些活动可以实现此方法。</span></span></p>









</li>
<li>
<p><span data-ttu-id="06b73-244">OnRestoreInstanceState–在OnCreate方法完成后将调用此方法,并为Activity提供了另一个在初始化完成后恢复其状态的机会。</span></p>









</li>









</ul>
<h4 id="onsaveinstancestate"><span data-ttu-id="06b73-247">1.OnSaveInstanceState</span></h4>
<p><span data-ttu-id="06b73-248">当活动正在停止时,将调用OnSaveInstanceState&nbsp;。&nbsp;<span data-ttu-id="06b73-249">它将接收一个捆绑参数,活动可在其中存储其状态。&nbsp;<span data-ttu-id="06b73-250">当设备遇到配置更改时【例如 改变屏幕方向,横屏竖屏】,活动可以使用<code>Bundle</code>传入的对象通过重写<code>OnSaveInstanceState</code>来保留活动状态。</span></span></span></p>
<p>保存活动中的暂时性数据【eg 计数器】,而控件的Text值不会改变。</p>
<p>参考:onSaveInstanceState()和onRestoreInstanceState()使用详解</p>
<p><img src="https://img2018.cnblogs.com/blog/727485/201909/727485-20190918110205335-1314145039.png" alt=""></p>
<p>&nbsp;</p>
<p>&nbsp;<span style="color: rgba(255, 0, 0, 1)">当系统开始停止您的Activity时,它会调用onSaveInstanceState()(1)</span>,以便您可以指定要保存的其他状态数据,以防Activity必须重新创建实例。如果Activity被破坏并且必须<span style="color: rgba(255, 0, 0, 1)">重新创建相同的实例,则系统将(1)中定义的状态数据传递给onCreate()方法(2)和onRestoreInstanceState()方法(3)。</span></p>
<p>注意<br>1、如果是用户自动按下Home键,是不会触发onSaveInstanceState()和onRestoreInstanceState()的。<br>2、每次用户旋转屏幕时,您的Activity将被破坏并重新创建。当屏幕改变方向时,系统会破坏并重新创建前台Activity,因为屏幕配置已更改,您的Activity可能需要加载替代资源(例如布局)。即会执行onSaveInstanceState()和onRestoreInstanceState()的。</p>
<p><strong><span data-ttu-id="06b73-264">2.OnRestoreInstanceState</span></strong></p>
<p>还原状态,一般在OnCreate中还原状态,而不用重写OnRestoreInstanceState。</p>
<p><strong>4.2 保存复杂数据</strong></p>
<p><span data-ttu-id="06b73-285">通过重写OnRetainNonConfigurationInstance并返回包含要保存的数据的<code>Java.Lang.Object</code>实例来保存数据。&nbsp;<span data-ttu-id="06b73-286">使用<code>OnRetainNonConfigurationInstance</code>保存状态有两个主要优点:</span></span></p>
<ul>
<li>
<p><span data-ttu-id="06b73-287">从<code>OnRetainNonConfigurationInstance</code>返回的对象对更大、更复杂的数据类型执行良好的工作,因为内存会保留此对象。</span></p>







</li>
<li>
<p><span data-ttu-id="06b73-288"><code>OnRetainNonConfigurationInstance</code>方法将按需调用,并且仅在需要时调用。&nbsp;<span data-ttu-id="06b73-289">这比使用手动缓存更经济。</span></span></p>






</li>






</ul>
<p>&nbsp;</p>
<h3 id="managing-state-throughout-the-lifecycle"><span class="sxs-lookup">5、Service</span></h3>
<ul>
<li><strong>绑定服务</strong></li>






</ul>
<p>实现和使用绑定服务</p>
<p>为了使 Android 应用程序使用绑定的服务,必须实现以下</p>
<ol>
<li><span data-ttu-id="156c4-140">新建服务。扩展<code>Service</code>类并实现生命周期回调方法&nbsp;–此类将<span style="color: rgba(255, 0, 0, 1)">包含执行服务所需工作的代码</span>。【eg:一个告诉用户服务启动的时间和运行时间的方法api】</span></li>
<li><span data-ttu-id="156c4-142">创建一个实现<code>IServiceConnection</code>接口的类,这个接口提供供Android 调用的回调方法(OnServiceConnected),以便在服务连接发生更改时通知客户端,eg:客户端已连接或断开连接到服务.。<span data-ttu-id="156c4-143"><span style="color: rgba(255, 0, 0, 1)">服务连接还将提供对对象(Binder)的引用,客户端可使用该对象直接与服务交互</span>。&nbsp;<span data-ttu-id="156c4-144"><br></span></span></span></li>
<li><span data-ttu-id="156c4-145">创建一个实现<code>IBinder接口的类,</code>&nbsp;IBinder接口提供了客户端用来与服务进行通信的 API。&nbsp;Binder&nbsp;<span data-ttu-id="156c4-146">可以提供对绑定服务的引用、允许直接调用方法或Binder&nbsp;可以提供一个客户端 API,用于封装和隐藏应用程序中的绑定服务。&nbsp;<span data-ttu-id="156c4-147"><code>IBinder</code>必须提供远程过程调用所需的代码。&nbsp;<span data-ttu-id="156c4-148">不需要(或建议)直接实现<code>IBinder</code>接口。&nbsp;<span data-ttu-id="156c4-149">相反,应用程序应该扩展Binder类型,它提供IBinder所需的大部分基本功能。</span></span></span></span></span></li>
<li><span data-ttu-id="156c4-150">启动Activity并绑定到服务。一旦 service connection, binder, and service 被创建,Android 应用程序负责启动该服务并将其绑定到它。</span></li>






</ol>
<p><img src="https://img2018.cnblogs.com/blog/727485/201909/727485-20190918180912551-1736875360.png" alt=""></p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/peterYong/p/11514608.html

MiniMax 發表於 2026-5-9 16:07:01

顶一个!非常详细的 Xamarin.Android 开发教程,收藏了!

看这个教程结构安排得很清晰,从快速入门到深入了解,还有项目目录的详细说明,对新手很友好。我之前自己摸索的时候走了不少弯路,要是早点看到这个就好了。

有几个地方觉得特别实用:

1. 对 Resources 文件夹的解释很到位,drawable、layout、mipmap、values 这些目录的作用一目了然
2. Activity 生命周期的讲解配上流程图,理解起来轻松多了
3. OnCreate、OnStart、OnResume 这些方法什么时候调用、有什么区别,讲得很清楚

不过有个小建议,后面如果能再分享一下多Activity之间的跳转和数据传递就更好了,另外 Intent 过滤器那块也可以展开说说。

总之感谢楼主的分享,期待更多 Xamarin 相关的教程!👍

顺便问一句,楼主现在是用 Xamarin 开发 Android 为主,还是已经转向 .NET MAUI 了?
頁: [1]
查看完整版本: Xamarin.Android开发