ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 应用基础 --- Android应用程序是用Java编程语言编写的。Android SDK工具将您的代码以及任何数据和资源文件编译成APK,一个包含后缀的存档文件的Android包.apk。一个APK文件包含Android应用程序的所有内容,是Android设备用于安装该应用程序的文件。 每个Android应用程序都在自己的安全沙箱中,受到以下Android安全功能的保护: * Android操作系统是一个多用户Linux系统,其中每个应用程序是不同的用户。 * 默认情况下,系统为每个应用程序分配一个唯一的Linux用户ID(该ID仅由系统使用,对应用程序而言是未知的)。该系统为应用程序中的所有文件设置权限,以便只有分配给该应用程序的用户标识才能访问它们。 * 每个进程都有自己的虚拟机(VM),所以应用程序的代码与其他应用程序隔离。 * 默认情况下,每个应用程序都在自己的Linux进程中运行。当任何应用程序的组件需要执行时,Android系统启动该过程,然后在不再需要时关闭该进程,或者系统必须为其他应用程序恢复内存。 Android系统实现最低权限的原则。也就是说,默认情况下,每个应用程序只能访问它所需的组件来完成其工作,而不再需要。这创建了一个非常安全的环境,其中应用程序无法访问未向其授予权限的系统的部分。但是,有一些应用程序可以与其他应用程序和应用程序共享数据以访问系统服务的方法: * 可以安排两个应用程序共享相同的Linux用户ID,在这种情况下,他们可以访问对方的文件。为了节省系统资源,具有相同用户ID的应用程序也可以安排在同一个Linux进程中运行并共享同一个虚拟机。应用程序也必须使用相同的证书进行签名。 * 应用程序可以请求访问设备数据的权限,例如用户的联系人,SMS消息,可安装存储(SD卡),摄像头和蓝牙。用户必须明确授予这些权限。有关详细信息,请参阅 使用系统权限。 本文档的其余部分介绍以下概念: * 定义应用程序的核心框架组件。 * 您在其中声明组件的清单文件以及应用程序所需的设备功能。 * 与应用程序代码分离的资源,允许您的应用程序优化其各种设备配置的行为。 ## 应用程序组件 应用程序组件是Android应用程序的基本构件。每个组件是系统或用户可以通过该入口点输入您的应用程序的入口点。一些组件依赖于其他组件。 有四种不同类型的应用程序组件: * 活动 * 服务 * 内容提供商 * 广播接收机 每种类型都具有不同的用途,并且具有明确的生命周期,定义组件的创建和销毁。以下部分描述了四种类型的应用程序组件。 ### 活动 一个活动是用于与用户交互的入口点。它表示具有用户界面的单个屏幕。例如,电子邮件应用可能有一个活动显示新的电子邮件列表,另一个组成电子邮件的活动,以及另一个阅读电子邮件的活动。虽然这些活动在一起形成了电子邮件应用程序中的一致性用户体验,但每个人都独立于其他应用程序。因此,如果电子邮件应用程序允许,其他应用程序可以启动任何一个这样的活动。例如,相机应用程序可以在组成新邮件的电子邮件应用程序中启动活动,以允许用户共享图片。一个活动有助于系统和应用之间的以下关键交互: * 跟踪用户目前关心的内容(屏幕上是什么),以确保系统持续运行托管活动的进程。 * 知道以前使用的进程包含用户可能返回(停止的活动)的内容,从而更加高度地保持这些进程的优先级。 * 帮助应用程序处理程序被杀死,以便用户可以恢复到先前状态的活动。 * 为应用程序提供一种方式来实现彼此之间的用户流,并为系统协调这些流。(这里最经典的例子是分享) 您将一个活动作为Activity该类的子类实现。有关更多信息,Activity中 活动开发指南。 ### 服务 一个服务是一个通用的入口点,用于保持应用在后台运行的各种原因。它是在后台运行以执行长时间运行的操作或为远程进程执行工作的组件。服务不提供用户界面。例如,当用户处于不同的应用程序时,服务可能会在后台播放音乐,或者可能通过网络获取数据而不会阻止用户与活动的交互。另一个组件(如活动)可以启动服务,让它运行或绑定到它,以便与之进行交互。实际上有两个非常明显的语义服务告诉系统如何管理一个应用程序:已启动的服务告诉系统保持运行,直到他们的工作完成。 这可能是即使在用户离开应用程序后,也可以在后台同步一些数据或播放音乐。在后台同步数据或播放音乐也代表了两种不同类型的启动服务,它们修改系统如何处理它们: * 音乐播放是用户直接意识到的,所以应用程序告诉系统这是通过说它想成为前台,通知告诉用户它; 在这种情况下,系统知道应该尽量保持该服务的进程正常运行,因为用户将不快乐。 * 常规后台服务不是用户直接意识到的运行,所以系统在管理进程方面有更大的自由。它可能允许它被杀死(然后稍后重新启动服务),如果它需要RAM用于用户更直接关心的事情。 绑定的服务运行是因为某些其他应用程序(或系统)已经表示要使用该服务。这基本上是为另一个进程提供API的服务。因此,系统知道这些进程之间存在依赖关系,因此如果进程A绑定到进程B中的一个服务,它就知道需要保持进程B(及其服务)运行A.另外,如果进程A是某事用户关心,那么它也知道将进程B视为用户关心的内容。由于其灵活性(更好或更差),服务已经成为各种上级系统概念的真正有用的基础。动态壁纸,通知听众,屏幕保护程序,输入法,无障碍服务, 一个服务被实现为一个子类Service。有关Service课程的更多信息,请参阅“ 服务开发人员指南”。 注意:如果您的应用定位到Android 5.0(API级别21)或更高版本,请使用JobScheduler该类来调度操作。JobScheduler具有通过优化调度作业来节省电池的优点,以降低功耗,并通过使用Doze API。有关使用此类的更多信息,请参阅JobScheduler 参考文档。 ### 广播接收机 一个广播接收器是使系统能够提供事件给应用程序一个普通的用户流量之外,使应用系统范围的广播通告响应的组件。由于广播接收机是应用程序中的另一个明确定义的条目,所以系统甚至可以向当前运行的应用程序发送广播。所以,例如,一个应用程序可以安排一个警报来发布通知,告诉用户一个即将到来的事件...并且通过将该闹钟传递给该应用的BroadcastReceiver,没有必要让该应用保持运行,直到闹钟熄灭 许多广播来源于系统 - 例如,广播宣布屏幕已经关闭,电池电量不足或被捕获。应用程序还可以启动广播 - 例如,让其他应用程序知道某些数据已经下载到设备,并可供他们使用。虽然广播接收机不显示用户界面,但是它们可以创建状态栏通知 ,以在广播事件发生时提醒用户。然而,更常见的是,广播接收机只是通往其他组件的网关,并且旨在进行非常少量的工作。例如,它可以JobService根据事件计划执行一些工作 广播接收机只是通往其他组件的网关,并且旨在进行非常少量的工作。例如,它可以根据事件计划执行一些工作 广播接收机只是通往其他组件的网关,并且旨在进行非常少量的工作。例如,它可以根据事件计划执行一些工作JobScheduler \ 广播接收机被实现为子类BroadcastReceiver ,每个广播作为Intent对象传送。有关更多信息,请参阅BroadcastReceiver课程。 内容提供商 一个内容提供商管理一组共享,你可以在文件系统中存储,在SQLite数据库,在网络上,或者在您的应用程序可以访问任何其他持久性存储位置的应用程序的数据。通过内容提供商,如果内容提供商允许,其他应用程序可以查询或修改数据。例如,Android系统提供管理用户联系信息的内容提供商。因此,具有适当权限的任何应用程序都可以查询内容提供者,例如 ContactsContract.Data,读取和写入有关特定人员的信息。将内容提供者视为数据库中的抽象是有诱惑力的,因为针对这种常见情况,内置提供程序存在大量的API和支持。然而,它们与系统设计的核心目的不同。对于系统, 内容提供商是用于发布由URI方案标识的命名数据项的应用程序的入口点。因此,应用程序可以决定如何将其包含的数据映射到URI命名空间,将这些URI发送给可以依次使用它们访问数据的其他实体。系统在管理应用程序时可以使用一些特殊的操作: 分配URI不要求应用程序保持运行,所以URI可以在他们拥有的应用程序退出后持续存在。该系统只需要确保拥有的应用程序仍然在运行,当它必须从相应的URI检索应用程序的数据。 这些URI还提供了一个重要的细粒度安全模型。例如,应用程序可以将剪贴板上具有的图像的URI放置在其中,但将其内容提供商锁定,以便其他应用程序不能自由访问它。当第二个应用程序尝试访问剪贴板上的URI时,系统可以允许该应用通过临时URI许可授权访问数据, 以便允许其访问该URI后面的数据,但第二个应用程序中没有其他内容。 内容提供商也可以读取和写入您的应用程序私有的数据,而不是共享数据。例如,Note Pad示例应用程序使用内容提供商来保存笔记。 内容提供者实现为子类,ContentProvider 并且必须实现一组标准的API,以使其他应用程序能够执行交易。有关更多信息,请参阅内容提供商开发人员指南。 Android系统设计的独特之处在于,任何应用都可以启动其他应用的组件。例如,如果您希望用户使用设备摄像头捕获照片,则可能还有另一个应用程序可以使用该应用程序,而不是开发自己拍摄照片的活动。您不需要整合或甚至链接到相机应用程序的代码。相反,您可以在拍摄照片的相机应用程序中简单地启动该活动。完成后,照片甚至可以返回到您的应用程序,以便您可以使用它。对于用户来说,好像相机实际上是您的应用程序的一部分。 当系统启动组件时,如果该应用程序尚未运行并实例化组件所需的类,那么它将启动该应用程序的进程。例如,如果您的应用程序在相机应用程序中启动捕获照片的活动,该活动将在属于相机应用程序的过程中运行,而不是在应用程序的进程中。因此,与大多数其他系统上的应用程序不同,Android应用程序不具有单个入口点(没有main()功能)。 由于系统在单独的进程中运行每个应用程序,而且具有限制访问其他应用程序的文件权限,因此您的应用程序无法从其他应用程序直接激活组件。但是,Android系统可以。要激活另一个应用程序中的组件,请将指定您启动特定组件的意图的消息传递给系统。系统然后为您激活组件。 激活组件 四种组件类型中的三种 - 活动,服务和广播接收器 - 被称为意图的异步消息激活。意图在运行时将各个组件彼此绑定。您可以将它们视为要求其他组件执行操作的使者,无论该组件是属于您的应用还是其他组件。 用一个Intent对象创建一个意图,该对象定义一个消息来激活特定组件(显式意图)或特定类型的组件(隐含意图)。 对于活动和服务,意图定义要执行的操作(例如, 查看或 发送某些内容),并且可以指定要执行的数据的URI,以及启动的组件可能需要知道的其他内容。例如,意图可能传达对活动的请求以显示图像或打开网页。在某些情况下,您可以开始一个活动来接收结果,在这种情况下,活动也会将结果返回到其中Intent。例如,您可以发出意图让用户选择个人联系人并将其返回给您。返回意图包括指向所选联系人的URI。 对于广播接收机,意图简单地定义正在广播的公告。例如,广播,以指示该设备的电池为低仅包括一个公知的操作字符串,表示电池电压低。 与活动,服务和广播接收器不同,内容提供商不会通过意图激活。相反,它们在被来自a的请求的目标时被激活ContentResolver。内容解析器处理与内容提供者的所有直接事务,以便与提供者执行事务的组件不需要而不是调用ContentResolver对象上的 方法。这在内容提供者和请求信息的组件(为了安全性)之间留下了一层抽象。 有单独的方法激活每种类型的组件: 你可以开始一个活动或给它一些新的东西传递一个做Intent给startActivity()或startActivityForResult() (当你想活动返回的结果)。 使用Android 5.0(API级别21)及更高版本,您可以使用JobScheduler该类来调度操作。对于早期的Android版本,可以启动服务(或提供新的指令来持续服务)通过传递Intent来startService()。你可以通过传递一个绑定到服务Intent到 bindService()。 你可以通过传递一个启动的广播Intent到方法,如 sendBroadcast(),sendOrderedBroadcast()或sendStickyBroadcast()。 你可以通过调用执行查询到内容提供商query()上ContentResolver。 有关使用意图的更多信息,请参阅意向和意图过滤器文档。以下文档提供有关激活特定组件的更多信息: 活动, 服务 BroadcastReceiver和 内容提供商。 清单文件 之前Android系统可以启动一个应用程序组件,系统必须知道该组件通过阅读应用程序的存在清单文件,AndroidManifest.xml。您的应用必须在此文件中声明其所有组件,该组件必须位于应用程序项目目录的根目录。 清单除了声明应用程序的组件之外还会执行一些操作,如下所示: 标识应用程序所需的任何用户权限,例如Internet访问或对用户联系人的读取权限。 声明 应用程序所要求的最低 API级别,基于应用程序使用的API。 声明应用程序使用或要求的硬件和软件功能,如相机,蓝牙服务或多点触控屏幕。 声明应用程序需要与(除Android框架API之外)(例如 Google Maps库)进行链接的API 库。 声明组件 清单的主要任务是通知系统应用程序的组件。例如,清单文件可以声明如下的活动: <?xml version = “1.0” encoding = “utf-8” ?> <manifest ... > <application android:icon = “@ drawable / app_icon.png” ... > <activity android:name = “com.example。 project.ExampleActivity“ android:label = ”@ string / example_label“ ... > </ activity> ... </ application> </ manifest> 在<application> 元素中,android:icon属性指向标识应用的图标的资源。 在该<activity>元素中,该android:name属性指定Activity子类的完全限定类名称,该android:label属性指定要用作活动的用户可见标签的字符串。 您必须使用以下元素声明所有应用程序组件: <activity> 活动要素 <service> 服务元素。 <receiver> 广播接收机的元素。 <provider> 内容提供商的元素。 在源中包含但不在清单中声明的​​活动,服务和内容提供者对于系统是不可见的,因此永远不会运行。然而,广播接收器可以在清单中声明,也可以在代码中动态地创建为 BroadcastReceiver对象,并通过调用向系统注册 registerReceiver()。 有关如何构建应用程序的清单文件的更多信息,请参阅AndroidManifest.xml文件文件 。 声明组件功能 如上所述,在激活组件中,您可以使用它 Intent来启动活动,服务和广播接收器。您可以在Intent intent 中使用明确命名目标组件(使用组件类名称)。您还可以使用隐含意图,其中描述要执行的操作的类型,以及可选的执行操作的数据。隐含意图允许系统在设备上找到可以执行操作并启动它的组件。如果有多个组件可以执行由意图描述的动作,则用户选择要使用的组件。 注意:如果您使用意图启动 Service,请使用明确的 意图确保您的应用程序安全 。使用隐含的意图启动服务是一个安全隐患,因为您无法确定什么服务将响应意图,并且用户无法查看哪个服务启动。从Android 5.0(API级别21)开始,如果bindService() 使用隐式意图调用,系统将抛出异常。不要为您的服务声明意图过滤器。 系统通过将接收到的意图与设备上其他应用程序的清单文件中提供的意图过滤器进行比较来识别可以对意图做出响应的组件。 当您在应用程序的清单中声明一个活动时,您可以选择包含声明活动功能的意图过滤器,以便其可以响应其他应用程序的意图。您可以通过将<intent-filter>组件的声明元素的子元素添加为元素来为组件声明一个意图过滤器。 例如,如果您构建具有撰写新电子邮件的活动的电子邮件应用程序,则可以声明一个意图过滤器以响应“发送”意图(以便发送新电子邮件),如以下示例所示: <manifest ... > ... <application ... > <activity android:name = “com.example.project.ComposeEmailActivity” > <intent-filter> <action android:name = “android.intent.action.SEND “ /> <data android:type = ”* / *“ /> <category android:name = ”android.intent.category.DEFAULT“ /> </ intent-filter> </ activity> </ application> </ manifest > 如果另一个应用程序创建了一个意图ACTION_SEND并将其传递给 startActivity(),系统可能会启动您的活动,以便用户可以起草并发送电子邮件。 有关创建意图过滤器的更多信息,请参阅意向和意图过滤器文档。 声明应用程式要求 有各种由Android提供的设备,并不是所有设备都具有相同的功能和功能。为防止您的应用程序安装在缺少应用程序所需功能的设备上,请务必通过在清单文件中声明设备和软件要求来清楚地定义应用程序支持的设备类型的配置文件。大多数这些声明仅供参考,系统不会阅读它们,但是外部服务(如Google Play)会读取它们,以便在用户从设备搜索应用程序时提供过滤。 例如,如果您的应用程序需要相机并使用Android 2.1(API 7 级)中引入的API,则必须将它们声明为清单文件中的要求,如以下示例所示: <manifest ... > <uses-feature android:name = “android.hardware.camera.any” android:required = “true” /> <uses-sdk android:minSdkVersion = “7” android:targetSdkVersion = “19” /> ... </ manifest> 通过示例中显示的声明,没有相机并且Android版本低于 2.1的设备无法从Google Play安装您的应用。但是,您可以声明您的应用程序使用相机,但 不需要。在这种情况下,您的应用程序必须设置required 属性"false",并在运行时检查设备是否有一个摄像头,并禁用任何拍照功能为宜。 有关如何管理应用程序与不同设备的兼容性的更多信息,请参阅设备兼容性 文档。 应用资源 Android应用程序不仅仅是代码,它需要与源代码分离的资源,例如图像,音频文件以及与应用程序可视化呈现相关的任何内容。例如,您可以使用XML文件定义动画,菜单,样式,颜色和活动用户界面的布局。使用应用程序资源可以轻松更新应用程序的各种特性,而无需修改代码。提供一组备用资源使您能够针对各种设备配置(如不同的语言和屏幕尺寸)优化您的应用程序。 对于您在Android项目中包含的每个资源,SDK构建工具定义了一个唯一的整数ID,您可以使用它来从应用程序代码或从XML定义的其他资源引用资源。例如,如果您的应用程序包含名为logo.png(保存在res/drawable/目录中)的映像文件,则SDK工具将生成一个名称的资源ID R.drawable.logo,可用于引用映像并将其插入到用户界面中。 提供资源与您的源代码分开的最重要的方面之一是能够为不同的设备配置提供替代资源。例如,通过在XML中定义UI字符串,您可以将字符串转换为其他语言,并将这些字符串保存在单独的文件中。那么Android的应用相应的语言字符串基于语言的UI 预选赛 ,你追加到资源目录的名称(如res/values-fr/法国字符串值)和用户的语言设置。 Android支持很多不同的预选赛为您替代资源。限定符是一个短字符串,您可以以资源目录的名称包含该字符串,以便定义应使用这些资源的设备配置。例如,您应该根据设备的屏幕方向和大小为您的活动创建不同的布局。当设备屏幕处于纵向(高)时,您可能希望具有垂直的按钮布局,但是当屏幕处于横向(宽)时,可以水平对齐按钮。要根据方向更改布局,您可以定义两个不同的布局,并将适当的限定符应用于每个布局的目录名称。然后, 有关您可以在应用程序中包含的各种资源的更多信息,以及如何为不同的设备配置创建替代资源,请阅读“ 提供资源”。