Android(1)——Application Fundamentals

原文地址:Application Fundamentals


APK:Android package,以.apk为后缀,是一种档案文件,它包含一个应用程序安装需要的所有内容。


一旦将某个软件安装到手机上后,每个Android app都会有它自己的安全池:

1. Android操作系统是一个multi-user Linux system,其中每个app都是一个不同的user。

2. 默认情况下,Android系统会给每一个app一个特定的唯一的user ID,这个ID只有系统知道,app自己是不知道的,只有在系统中为某个app ID赋予了某些权限以后这个app才有权利使用它已有的权限。

3. 每个process都有他自己的虚拟机virtual machine(VM),所以每个app的代码是独立运行的。

4. 默认情况下,每个app运行在它自己的Linux process中,当一个app中的某个组件需要执行时系统启动这个process,当某个process不再需要执行或者系统需要为其他app释放内存的时候会关闭这些process。


Android system为每个app设置最小权限,也就是每个app只拥有它所需的那部分权限来创造一个安全的环境。


当然也有很多共享数据或者使用系统服务的方法:

1. 可以让两个app拥有相同的Linux user ID,这样它们可以互相访问对方的文件。为了保护系统的资源,拥有相同user ID的app可以运行在相同的Linux进程中,共享VM(拥有相同的certificate)

2. 一个app可以请求系统服务的权限,例如联系人,短信,SD card,照相机,蓝牙等。这些权限必须在安装的时候赋予。


App Components:

1. Activities:

一个activity代表一个单屏幕,比如一个邮件软件包含多个activity,它们彼此独立。每个活动都可能在某个app中启动(如果授权了的话)。

2. Services:

运行在后台去执行一个耗时的长时间的操作,或者去运行一些远程任务。它并没有界面,例如在后台放音乐,下载数据。

需要另外的一个组件例如activity来启动一个service,同时控制它的执行和绑定。

3. Content providers:

它用来实现app之间数据共享。我们可以将数据存储在文件系统、SQLite数据库、网络或者其他app可以访问的永久性存储地址。通过content provider,app就可以访问和修改它所授权的数据,例如某个app修改联系人信息。

Content provider还可以用来读写它自己但不共享的数据。

4. Broadcast receivers:

广播嘛。大多数的广播来自于系统,例如屏幕关闭、电池电量低或者拍照了。App也可以自己创建广播,比如让其他的app知道一些数据已经下载好了然后提醒它们可以去访问了。尽管它没有一个界面,但是它可以创建一个status bar notification去提醒用户有广播事件。平时的时候,其实广播只会做一些超简单的工作,提醒的功能比较多。

Android system有一个特别之处就是任何app都可以启动另一个app的组件,例如你想用照相机拍照,而另一个app实现了这个功能,那么你就可以用这个app的拍照功能,而不是说自己要写一个activity来自己实现拍照功能。


当系统启动一个组件的时候,会为这个app创建一个进程,实例化组件中的类。例如,当你的app需要使用照相机的那个活动时,这个活动进程是属于照相机这个app的,而不是你的app进程。所以不想其他多数的app系统,Android app可以有多种进入方式,不止main()。


在Android system中允许一个app的activity在没有授权的前提下直接启动另一个app的组件。你可以通过给那个发送一个你的特殊的intent来实现对其他app组件的启动。


Activating Components

activities、services and broadcast receivers 这三个组件可以通过异步消息intent来启动。Intent可以实现各个组件之间的关联关系,这个各个组件可以是不同app的。

对于activities和services而言,一个intent用来去执行一个动作或者打开某个URL连接。通过intent还可以发送和接收Intent携带的信息。

而对于broadcast receivers,Intent仅仅只是简单的宣布一些消息,比如电池电量低。


Content provider并不是通过intent来启动的,它是通过ContentResolver请求来启动的。

The content resolver handles all direct transactions with the content provider so that the component that's performing transactions with the provider doesn't need to and instead calls methods on the ContentResolver object. This leaves a layer of abstraction between the content provider and the component requesting information (for security).


总结一下启动各个组件的方法:

activity:Intent的startActivity() 或 startActivityForResult()。

service:Intent的startService() 或 bindService()。

broadcast:Intent的sendBroadcast() 或 sendOrderedBroadcase() 或 sendStickyBroadcase()。

content provider:by calling query() on a ContentResolver。


The Manifest File

在Manifest文件中必须要声明它所有的组件。除此之外还有一些需要声明的东西:

1. app所需的user permissions。

2. 声明minimum API Level。

3. 声明使用的硬件和软件特性,例如照相机,蓝牙服务或者多点触控屏幕(multitouch screen)。

4. app所需要的API libraries,例如Google Maps library。

5. 等等


Declaring components

举例吧,声明一个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

In the <application> element, the android:icon attribute points to resources for an icon that identifies the app.

In the <activity> element, the android:name attribute specifies the fully qualified class name of the Activitysubclass and the android:label attributes specifies a string to use as the user-visible label for the activity.

You must declare all app components this way:

不要在Manifest文件中声明不可见的activity、service and content providers,从来不会运行的。

而broadcast receivers可以在Manifest中声明,也可以在代码中通过registerReceiver()动态的创建和注册。


Declaring component capabilities

通过上面的讨论,在启动一个组件的时候,我们可以通过Intent来启动activity、service和broadcast receiver。我们可以直接在Intent中显示的用目标组件的名称来启动组件,然而,Intent真正的魅力在于使用隐式Intent。

An implicit intent simply describes the type of action to perform (and, optionally, the data upon which you’d like to perform the action) and allows the system to find a component on the device that can perform the action and start it.

如果intent中有多个组件,那么需要通过用户来进行选择。系统识别不同的组件需要通过在Manifest文件中声明的intent filters来进行筛选。

我们可以在app的Manifest文件中给activity随意的声明intent filter属性。

For example, if you've built an email app with an activity for composing a new email, you can declare an intent filter to respond to "send" intents (in order to send a new email) like this:

<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>
Then, if another app creates an intent with the  ACTION_SEND  action and pass it to  startActivity() , the system may start your activity so the user can draft and send an email.

Declaring app requirements

Android system可能会在各种各样的设备上运行,但这些设备却不能提供相同的硬件条件,那为了阻止你的程序被安装在缺少功能的设备上,那我们就应该通过声明设备和软件要求在你的Manifest文件中。大多数的这些声明都只是信息,系统也并不会读它们,但是外部服务例如Google Play就要阅读它们,为了让用户在寻找符合他们设备的app时提供筛选条件。

For example, if your app requires a camera and uses APIs introduced in Android 2.1 (API Level 7), you should declare these as requirements in your manifest file like this:

<manifest ... >
    <uses-feature android:name="android.hardware.camera.any"
                  android:required="true" />
    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="19" />
    ...
</manifest>
这样声明以后,不具备照相机或者Android version低于2.1的设备将不能从Google Play上安装你的app。


当然还有一种动态的方式就是将上面的required设置为false,当用户设备使用时根据设备的条件来更改这个值来决定是否启用照相机功能。



App Resources

一个Android app不仅仅是由代码组成的,它还需要很多的resources,例如图片,audio files或者其他一切与app相关联的东西。例如你需要定义动画、菜单、styles、colors以及用户界面的布局文件。利用app resources可以避免修改代码而更新app的版本,也便于让你的app有更多的配置,例如不同的语言,屏幕大小等。


对于每个你放进Android project中的resource,SDK build tools都会为它们设置一个唯一的ID,这样你可以在你的程序中通过这个ID来使用这些resource。

For example, if your app contains an image file named logo.png (saved in the res/drawable/ directory), the SDK tools generate a resource ID named R.drawable.logo, which you can use to reference the image and insert it in your user interface.


将resources和你的代码分别存放的一个很重要的原因就是你可以为你的app提供多种resouces版本选择,当你的app面对不同的设备时,它可以自动对应做出合适的选择。这就是之间也遇到过的关于限定符的应用。

For example, by defining UI strings in XML, you can translate the strings into other languages and save those strings in separate files. Then, based on a languagequalifier that you append to the resource directory's name (such as res/values-fr/ for French string values) and the user's language setting, the Android system applies the appropriate language strings to your UI.

Android提供多种不同的限定符qualifiers来实现你的可选项。限定符qualifier是一个short string,你要把它写在你的resource directories目录的名称里。

 As another example, you should often create different layouts for your activities, depending on the device's screen orientation and size. For example, when the device screen is in portrait orientation (tall), you might want a layout with buttons to be vertical, but when the screen is in landscape orientation (wide), the buttons should be aligned horizontally. To change the layout depending on the orientation, you can define two different layouts and apply the appropriate qualifier to each layout's directory name. Then, the system automatically applies the appropriate layout depending on the current device orientation.

上面讲的例子就是在手机横屏和竖屏时app自动切换不同的布局显示。











  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值