Android 应用程序的组成部分
Android应用程序由各个组件组成,并使用Manifest绑定到一起,Manifest描述了每一个组件和它们之间的交互方式,还用于指定权限,硬件,平台以及应用程序的元数据等信息。
应用程序的基本组成模块
- Activity
应用程序的表示层,程序的每一个UI都是通过Activity类来显示的,Activity使用Fragment和视图来布局和显示信息,以及响应用户的操作。
- Service
应该用程序中不可见的工作者 ,Service运行时没有UI,可以更新数据源和Activity,触发通知和广播Intent,用来执行运行时间长的任务或者不需要交互的任务。
- Content Provider
可共享的持久数据储存器 。Content Provider用来管理和持久化应用程序数据,通常会与SQL数据库交互。Content Provider是应用之间共享数据的首选方法。可以配置自己的Content Provider来允许其他应用程序访问。
- Intent
应用程序间的消息传递框架。Android 中大量使用了Intent,包括启动和停止Activity和Service,在系统范围内或向目标Activity、Service或Broadcast Receiver广播消息,以及请求对特定的一条数据执行操作。
- Broadcast Receiver
Intent侦听器,主要用于接受广播,接受特定事件,以便执行相应的操作
- Widget
通常添加到设备主屏幕的可视化应用程序组件。Widget是Broadcast Receiver的特殊变体,可用于创建动态的交互式应用程序组件,用户可以把这些组件添加到主屏幕上。
- Notification
Notification允许向用户发送信号,该组件是程序不可见或者不活动时吸引用户注意的首选方法。
Manifest文件
每个Android应用都有一个Manifest文件,Manifest定义应用程序及其组件和需求的结构和元数据。
它包含组成应用程序的每一个Activity、Service、Content Provider和Broadcast Receiver的节点,并使用Intent Filter和权限来确定组件之间的以及这些组件和其他应用程序是如何交互的。Manifest文件由一个根manifest标签构成,该标签有一个项目包的package属性,该属性作为改应用程序的唯一标识。
Manifest的各个属性如下:
- versionCode
作为应用程序版本迭代的时候使用
- versionName
展示给用户的公共版本号
- installLocation
指定是否允许将应用程序安装到外部存储器,可用参数preferExternal或auto,前者只要有可能就安装在外部存储器,后者由系统处理
- uses-sdk
定义minSDKVersion和targetSDKVersion,minSDKVersion保证在这个SDK版本及其以上运行,targetSDKVersion用于指定开发和测试应用程序时使用的平台,尽可能设置该版本为最新的SDK版本。
- uses-feature
使用多个uses-feature来指定应用程序需要的每个硬件功能,如
<uses-feature android:name="android.hardware.microphone" android:required="false"/>
复制代码
还可以用来指定OpenGL的最低版本,版本号为32位,高16位为主版本号,低16位为次版本号,如
<uses-feature android:glEsVersion="0x00010001"/>
复制代码
- uses-permission
权限申请,Android为了安全,在使用某些服务的时候需要权限,如拨打电话,读取联系人等
- application
一个Manifest只有一个application节点,application节点中包括了四大组件的子节点。
- activity
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
复制代码
- service
<service android:name=".MyService"/>
复制代码
- provider
<provider
android:authorities="com.fengwei.app.MyContentProvider"
android:name=".MyContentProvider"/>
复制代码
- receiver
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
</intent-filter>
</receiver>
复制代码
- uses-library
指定应用程序共享库。
Android资源文件
在Android res文件目录下包含drawable、values、layout文件等,逐个介绍
- drawable
drawable文件夹下存放图片资源,但Android碎片化严重,屏幕大小不一,分辨率各不相同,所以会有不同分辨率的drawable文件夹,如drawable-hdpi,drawable-xhdpi,drawable-xxhdpi等
- strings
<string name="title_draw_histogram">直方图</string>
复制代码
- styles
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
复制代码
- colors
<color name="colorPrimary">#3F51B5</color>
复制代码
- dimens
<dimen name="large">16sp</dimen>
复制代码
- layout
布局文件,在XML文件中设计用户界面布局,使界面和业务逻辑分离出来。
Android支持属性动画、补间动画、帧动画。
- 属性动画
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000"
android:interpolator="@android:anim/accelerate_interpolator"
android:propertyName="scaleX"
android:repeatCount="2"
android:repeatMode="reverse"
android:valueFrom="0"
android:valueTo="360"
android:valueType="floatType" />
复制代码
- 补间动画
动画类型 | 属性值 | 有效值 |
Alpha | fromAlpha/toAlpha | 0~1 |
Scale | fromXScale/toXScale fromYScale/toYScale pivotX/pivotY(0%~100%) | 0~1 |
Translate | fromX/toX fromY/toY | 0~1 |
Rotate | fromDegrees/toDegrees pivotX/pivotY(0%~100%) | 0~360 |
- 帧动画
创建Drawable的序列,做一个来连续的动画。
运行时配置更改
Android运行时可以更改语言,位置,硬件,有时候默认行为不是很方便,如屏幕旋转不希望重新创建Activity
要让Activity可以监听运行时配置更改,需要向它的manifest节点添加一个 android:configChanges
属性,说明希望对哪些配置更改进行处理。
- mcc和mnc 检测到SIM,并且它们的国家和网络发生了变化
- locale用户改变了设备的语言设置
- keyboardHidden显示或者隐藏了键盘或其他输入机制
- keboard对键盘类型进行了更改
- fontsize用户更改了首选的字体大小
- uiMode整体UI模式发生了变化,黑白切换
- orientation屏幕发生了旋转
- screenLayout屏幕布局发生了变化
- screenSize可用屏幕尺寸改变
- smallersScreenSize物理屏幕尺寸改变
在特定情况下,多个事件可能同时触发。
Activity 应用程序生命周期
每个Android应用程序都是通过自己的进程运行的,每一个进程都运行在独立的Dalvik实例中。每一个应用程序的内存和进程管理都是由运行时处理的。进程被终止的顺序由应用程序的优先级决定的,一个应用程序的优先级等同于它的优先级最高的组件的优先级。 当两个应用程序有相同的优先级时,在较低优先级状态运行时间最长的进程将会首先被终止。进程的优先级也受到进程间依赖关系的影响。应用进程分为活动进程、可见进程、启动Srevice进程,后台进程、空进程。
- Active 进程
正在前台运行的进程,这些进程数量非常少。Active进程包括:
- 处于活动状态的Activity
- 正在执行OnReceive事件处理程序的BroadCast Receiver
- 正在执行onStart、onCreate、onDestroy事件处理程序的Service
- 正在运行,且已被标记为前台运行的Service
- 可见进程
可见但是非活动进程,可以被用户看到,但是不在前台运行,如被dialog挡住的Actvity,这类进程数量也很少,不会轻易被终止。
- 启动Service进程
已经启动的Service进程,它们的优先级低于可见Activity和前台Service,在活动或者可见的进程需要资源时,会终止它们。当系统杀死一个Service后,会在资源可用时重启该Service,除非告诉系统不这么做(设置onStartCommand的返回值)
- 后台进程
不可见,并且没有任何运行Service或者Activity的进程,通常有很多这种进程,当前台资源不够时会优先终止它们。
- 空进程
Android会把生存周期结束后的应用程序保存在内存中。目的是为了减少应用程序被再次启动时的启动时间。这些进程会被定期终止
Actvity的创建
一个Activity一个屏幕,Activity类呈现了一个封装了窗口显示处理功能的空白屏幕,需要UI控件进行填充,要把UI分给一个Activity需要在Actvity的onCreate方法中调用setContentView。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
复制代码
创建好了Actvity需要在Manifest注册:
<activity
android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
复制代码
Activity的生命周期
- Activity栈
每一个Activity的状态由它在Activity栈中所处的位置决定,Activity栈是当前所有正在运行的Activity的集合。一个新的Activity启动时,它就变为Activity类,并移动到栈顶。如果用户点击了Back按钮,会回到上一个Activity,上一个Activity就会回到栈顶,变为活动状态。
[图片上传失败...(image-fc5494-1513087424368)]
- Activity的状态
随着Activity的创建和销毁,会在栈中进进出出,Activity会有四种状态:
- 活动状态
当Activity位于栈顶时,它是可见的,具有焦点的前台Activity,这时与用户进行交互,优先级很高
- 暂停状态
Activity可见,但是没有获得焦点,不能和用户交互,但一个Activity完全不可见时,就处于停止状态
- 停止状态
Activity不可见,但其他地方需要内存时,它会成为被终止的首选对象,在停止状态,保存数据和当前UI的状态以及停止一些不必要的操作是很重要的。
- 非活动状态
Activity被终止之后,在启动之前就处于非活动状态,已经移出栈中。
- Activity状态改变的监听
Activity的事件处理程序如下,当Activity在完整的,可见的和活动的生存期之间转化时,它们会被触发。
public class Main2Activity extends AppCompatActivity {
//在完整生存期开始时调用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//初始化一个Activity并填充UI
}
//在onCreate方法完成后调用,用于恢复UI状态
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//从savedInstanceState恢复UI状态
//这个Bundle也被传递给OnCreate
//自Activity上次可见后,只有当系统终止了该Activity时,才会被调用
//在随后的Activity进程的可见生存期之前调用
}
@Override
protected void onRestart() {
super.onRestart();
//加载改变,知道Activity在此进程中已经可见
}
//在可见生存期开始时调用
@Override
protected void onStart() {
super.onStart();
//Activity可见,UI change
}
//在Activity 状态生存期开始时调用
@Override
protected void onResume() {
super.onResume();
//恢复Activity需要,但是当它处于不活动状态时被挂起,暂停UI更新,线程或者进程
//Activity状态生命周期结束时调用,用来保存UI状态的改变
}
//把UI状态改变保存到outState
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//如果进程被运行时终止并被重启,那么这个Bundle将被传递给onCreate和onRestoreInstanceState
}
//在Activity状态生存期结束时调用
@Override
protected void onPause() {
super.onPause();
//挂起不需要更新的UI更新,线程或者CPU密集的进程
//当Activity不是前台的活动状态的Activity时
}
//在可见生存期结束时调用
@Override
protected void onStop() {
super.onStop();
//挂起不需要的UI更新,线程或处理事件
//当Activity不可见时,保存所有的编辑或者状态改变
}
//在完整生存期结束时调用
@Override
protected void onDestroy() {
super.onDestroy();
//清理所有的资源,结束线程,关闭数据库连接等
}
}
复制代码
- Activity生存期
在一个Activity从创建到销毁的完整的生存期,它会经历活动生存期和可见生存期的一次或者多次重复。
- 完整生命期
使用onCreate初始化Activity:填充用户界面,获得Fragment的引用,分配对类变量的引用,将数据绑定到控件,启动service和定时器等。使用onDestory来清理onCreate创建的资源,关闭所有外部连接。
- 可见生存期
onStart和onStop之间的时间叫做可见生存期。Activity可见,但是没有焦点,不能交互。 onStop方法中暂停或者停止动画、线程、传感器监听器、GPS查找。定时器、Service或者更新UI的线程。
- 活动生存期
onResume和onPause之间的时间叫做活动生存期。Activity在前台,接受用户交互信息。一般在onPause中保存状态,停止Broadcast Receiver,onResume中重新注册Broadcast Receiver。