Android基础知识

来源:互联网 发布:红楼梦 知乎 编辑:程序博客网 时间:2024/06/05 20:46

Android基础知识

安装成功,这个Android程序就拥有了自己独立的运行沙盒(沙盒是在受限的安全环境中运行应用程序的一种做法,这种做法是要限制授予应用程序的代码访问权限。)

  1. Android操作系统是一个多用户的Linux系统,其中的每一个应用程序都是一个独立的用户。

  2. 默认地,系统会为每一个应用程序分配一个唯一的Linux用户ID(这个ID只能被系统使用,并且对于应用程序来说,这个ID是未知的)。系统为一个应用程序的所有文件 设置了权限,所以,只有分配给这个应用程序的用户ID可以访问它们。

  3. 每一个进程有它主机的虚拟机 (VM), 所以一个应用程序的代码会独立与其它的应用程序运行。

  4. 默认地,每一个应用程序在它自己的Linux进程中运行。Android会在一个应用程序的任何一个组件需要被调用的时候启动这个进程。然后,当没有任何组件被调用或者系统需要为其它应用程序回收内存的时候,就会 关闭这个进程。

通过这种方式,Android 系统实现了 最少特权原则。就是说,每一个应用程序,默认地,都只能调用它所需要的工作组件。 这就创造了这样一种非常安全的环境,在这个环境中,一个应用程序不能访问没有被授予其权限的系统部分。


尽管如此,也有很多途径可以让一个应用程序和其它的应用程序共享数据,也可以让一个应用程序去调用系统服务:

为两个应用程序分配同一个Linux用户ID是可行的,这样它们就能访问对方的文件。为了节约系统资源,拥有相同用户ID的应用程序也可以被运行于相同的Linux进程 并且共享VM(它们必须用相同的证书签名)。

应用程序可以通过请求权限来访问设备数据,例如联系人,SMS信息,可插拔存储(SD卡),相机,蓝牙,等等。所有的应用程序权限必须在安装的时候由用户授予。


Android系统设计的一个独特方面是,任何程序都可以启动其它程序的组件。 例如,如果你想让用户使用设备相机捕捉一个相片,有另外一个程序做这件事,那么你的程序将可以调用它, 而不是你自己开发一个拍照的activity。你不必从相机程序中嵌入代码或者连链接代码也不需要。取而代之地,你可以简单地启动相机程序中拍照的activity。 当拍照完成,相片就会返回给你的程序供你使用。从用户的角度,就好像相机就是你程序的一部分。

当系统启动一个组件,它其实就启动了这个程序的进程(如果这个进程还未被启动的话)并实例化这个组件所需要的类。 例如,如果你的程序启动了相机程序里的activity去拍照,这个activity实际上是运行在相机程序的进程里,而不是你自己的进程。 因此,不像其它系统里的程序,Android程序并不是单入口的(例如它没有main方法)。

由于系统把程序运行在一个个独立的进程中,并使用文件权限来限制对其它程序的访问,所以你的程序不能从其它程序中直接激活组件。 尽管如此,Android系统可以做到!激活一个其它程序的组件,你必须向系统发送一个信息,这个信息需要指定你的intent 来启动一个指定的组件。 然后系统就会为你激活这个组件。

激活组件

四分之三的组件类型—activitie, service, 和 broadcast receiver—是被一个叫做 intent的异步消息激活的。 Intent把不同的独立的组件在运行期绑定在一起(你可以把它们当作从其它组件中请求动作的消息), 无论这些组件属于你的或者其它的程序。

一个intent使用一个Intent 对象来创建, 它用于激活一个指定的或者指定类型的组件。— 一个intent可以分别是显示的或者隐式的。

对于activity和service来说,一个intent定义了将要执行的动作。(例如, 查看或发送什么)并且可以指定动作执行需要的数据URL(启动组件所需要知道的其它数据)。 例如,一个intent可能发送一个请求,让一个activity去显示一张图片或打开一个网页。 某些情况下,你可以启动一个activity来接收一个结果,此时,这个activity也通过一个Intent 来返回结果。 (例如, 你可以发送一个intent让用户获取一个个人联系人,并让这个结果返回给你—返回的intent就包含了一个指向你选择的联系人的URI)。

对broadcast receiver来说, intent只是简单地定义了需要广播的公告(例如,一个指明设备电池电量低的广播就只包含了一个已知的动作字符串:“电量低”)。

另外一个组件类型, content provider, 不是用intent来激活。 相对地,它是由一个 ContentResolver 发起的一个指向它的请求激活的。 这个content resolver掌握了所有content provider的直接事务,所以用这个provider来执行事务的组件不需要直接执行而是调用这个 ContentResolver 对象的方法。 它在content provider和这个组件请求信息之间放置了一个抽象层(为了安全)。

激活各种类型组件有不同的方法:

  1. 你可以启动一个activity(或者让让它来做一些新的工作)通过传递一个Intent给startActivity() 或者 startActivityForResult() (当你想让一个activity为你返回一个结果)。
  2. 你可以启动一个service(或者给一个正在运行的service发送新的指令)通过传递一个 Intent 给 startService()。 或者你可以绑定一个服务通过传递一个Intent 给 bindService()。
  3. 你可以初始化一个broadcast通过传递一个Intent给一些方法像 sendBroadcast(), sendOrderedBroadcast(), 或者 sendStickyBroadcast()。
  4. 你可以让content provider执行一个查询操作通过调用 ContentResolver的query() 方法。

配置文件

在Android系统能够启动一个程序组件之前, 系统必须通过读取程序的AndroidManifest.xml 文件 (“配置”文件)来知道这个组件是否存在。 你的程序必须在这个文件中声明它所有的组件。这文件必须放在程序项目的根目录中。

除了声明程序组件外,这个配置文件还做一些其它的工作,例如:

  • 确定程序需要哪些用户权限,例如网络访问或者读取用户的联系人。
  • 声明程序需要的最小的 API Level 这个要参照程序都使用了哪些API。
  • 声明程序使用或要求的硬件和软件特性,例如相机,蓝牙服务,或者多点触屏。
  • 程序需要链接的API类库(除Android framework API之外的类库),例如 Google Map类库。
  • 其它

声明组件

配置文件的主要任务是通知系统,该应用程序都使用了哪些组件。 例如,一个配置文件可以这样声明一个activity:

<?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的用户可见标签的字符串。

你必须像这样声明所有的组件:

<activity> activity的元素<service> service的元素<receiver> broadcast receiver的元素<provider> content provider的元素

你包含在你程序中但并没有在配置文件中声明的Activitie, service, 和 content provider 是不被系统识别的,因此,也无法运行。但是, broadcast receiver既可以在配置文件中声明,也可以在代码中被动态创建(作为 BroadcastReceiver 对象) 并且通过调用 registerReceiver() 注册于系统中。

声明组件的用途

如前文 激活组件的讨论中所说, 你可以使用一个Intent 来启动一个activitie, service, 和 broadcast receiver。你可以明确地(使用组件的类名)在intent中声明一个目标组件。 但是, intent最牛逼的地方其实是它的动作(action)概念, 使用action,你可以简单地描述以下你想执行的动作(并且你也可以指定你想把哪些数据放在这个动作上) 并且允许系统去寻找设备上可以执行这个动作的组件并启动它。如果有多个组件可以执行这个动作,那么由用户来决定哪个去执行。

系统识别能够响应intent的组件的方法是比较收到的intent和设备的其它程序的配置文件中的intent filters

你在程序的配置文件中声明组件的时候,你就可以选择性地包含intent过滤器来声明组件的功能,这样它就能响应由其它程序发起的intent。 你可以通过添加一个 作为你组件的子元素 来为你的组件声明一个intent过滤器。

例如,一个包含编辑新邮件页面的邮件程序可能要在配置文件中声明一个intent过滤器,以此作为入口来响应“发送”intent(为了发送邮件)。 你程序中的一个Activity就要创建一个包含”发送”动作(ACTION_SEND) 的intent,这样系统在你通过startActivity() 调用了这个intent时就去比较邮件程序的“发送”页面然后启动它。

0 0
原创粉丝点击