Android学习06Android应用程序的基本组件
一个Android应用程序可以由几个不同的组件构成,Android应用程序的基本组件包括:Activity,Service,BroadcastReceiver,ContentProvider和Intent.
不同的组件有不同的特性以及各自的生命周期,下面分别介绍:
1.Activity组件
Activity是最常见的一种Android组件,每个Activity都相当于一个屏幕,其为用户提供了进行交互的可视界面。应用程序可以根据需要包含一个或多个Activity,这些Activity一般都继承自android.app包下的Activity类,并且这些Activity之间的运行是相互独立的。
1.1运行态(running state)
此时Activity显示在屏幕前台,并且具有焦点,可以和用户操作进行交互,比如向用户提供信息,捕获用户单击按钮的事件并作处理。
1.2暂停态(paused state)
此时Activity失去了焦点,并被其他的运行态的Activity取代在屏幕前台显示。如果掩盖暂停态Activity的运行态Activity并不能铺满整个屏幕窗口或者具有透明效果,则该暂停态的Activity对用户依然可见,但是不可以与其进行交互
暂停态的Activity仍然保留其状态和成员其他信息,当前系统的内存非常匮乏时,暂停状态下的Activity会被结束掉以获得更多的资源。
1.3停止态(stopped state)
停止态的Activity不紧米有焦点,而且是完全不可见的,虽然其他也保留状态和成员等信息,停止态的Activity会在系统需要的时候杯结束。
Activity生命周期如下图:
Activity显示的内容可以有两种声明方式,第一种是通过XML配置文件来声明,第二种则是将屏幕设置为某一个继承自View类的对象
*通过XML配置文件声明
Activity的配置文件位于res目录下的layout目录中,一个配置文件相当于一个View容器,其中可以添加Android平台下的一些内置的View,如TextView,ImageView,Button等,也可以添加继承自View类的子类对象,还可以继续添加View容器
布局文件还指定了View对象在View容器中的排布方式,如线性布局(LinearLayout),表格布局(TableLayout)等。
新建的Activity类代码中 :setContentView(R.layout.main); //设置所要显示的XML配置文件
*通过View的子类对象声明
通过XML配置的文件将不同的View整合到一起用非常方便,但是留给开发人员的自主性不够大,尤其是进行游戏编程时,往往Android系统中已经存在的View无法满足要求,这种情况下一般会通过继承好扩展View来开发自己想要的用户界面。下面给一个通过View的子类对象表决定Activity显示内容
例子比较简单不做演示
Activity类代码如下:
public class SetActivityView extends Activity {
MyContentView myContentView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myContentView = new MyContentView(this);
setContentView(myContentView);
}
}
新建的View类代码如下:
public class MyContentView extends View{
public MyContentView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) { //重写View类绘制时的回调方法
Paint paint = new Paint() ; //创建画笔
paint.setTextSize(18); //设置字体大小
paint.setAntiAlias(true); //设置抗锯齿
paint.setColor(Color.RED); //设置字体颜色
canvas.drawText("这是通过继承好扩展View类实现显示", 0, 50, paint); //绘制字体到屏幕
}
}
2. Service组件
与Activity不同的是,Service没有提供与用户进行交互的表示层。Service是运行在后台的一种Android组件,当应用程序需要进行某种不需要前台显示的计算或者数据处理时,就就可以启动一个Service来完成,每个Service都继承自android.app包下的Service类。
Service一般由Activity或其他Context对象来启动,当启动Service之后,该Service将会在后台运行,即使启动这个Service的Activity或者其他组件的生命周期已经结束,Service仍然会继续运行,直到自己的生命周期结束为止。每个Service都应该在AndroidMainfest.xml中进行声明。Service的启动方式有两种,对应的生命周期也各不相同
2,1 通过startService方法启动
当系统调用startService方法时,如果该Service还未启动则依次调用其onCreate方法和onStart方法来启动。当其他Context对象调用stopService方法,Service调用自身的stopSelt或stopService方法才会停止Service操作
2.2 通过bindService方法启动
当系统调用bindService方法时,如果该Service未启动,则会调用onCreate方法完成初始化工作,然后会将该Service和Context对象(如Activity)进行绑定,当被绑定的Context对象销毁时,与之绑在一起的Service也会停止运行。
需要注意的是,尽管两种方式启动Service,但无论Service是通过什么方式启动的,都可以将其与Context对象绑定。
3.Broadcast Receiver组件
Broadcast Reciver同Service一样,并不是提供与用户交互的表示层,其是一种负责接收广播消息并对消息做出反应的组件。在Android的系统中就存在还能多这样的广播,比如电池电量过低或信号过低,系统就会发出广播进行通知。
应用程序如果需要响应某一个广播消息,应该注册对应的Broadcast Receiver对象,该对象继承自BroadcastReceiver类,该类位于android.content包下。这样一来当系统或另外的应用程序发出特定广播时,该应用程序就可以接受并做出回应,比如启动Activity
3.1 BroadcastReceiver发布广播的方式
发布一个广播比较容易,只需要在需要的地方创建一个Intent对象,将信息的内存和用于过滤的信息封装起来,通过调用Context.sendBroadcast方法,Context.sendOrderedBroadcast方法或者Context.sendStickyBroadcast方法将该Intent对象广播出去。这三种发布广播的方式区别:
通常,使用sendBroadcast或sendStickyBroadcast发送出去的Intent,所有满足条件的BroadcastReceiver都会执行其onReceive方法。但若有多个满足sendOrderedBroadcast方法发送出去其执行onReceive方法的顺序都是没有保证的。而通过sendOrderedBroadcast方法发送出去的Intent,会根据BroadcastReceiver注册时IntentFilter设置的优先级的顺序来执行onReceive方法,相同优先级的BroadcastReceiver执行onReceive方法的顺序是没有保证的。
sendStickyBroadcast主要不同的是,Intent在发送后会一直存在,并且在以后调用registerReceiver注册相匹配的Receiver时会把这个Intent对象直接返回给新注册的Receiver
3.2 BroadcastReceiver接收广播的方式
发布的广播实体是Intent,那么接收广播的时候就需要通过IntentFilter对象来进行过滤。BroadcastReceiver的生命周期比较简单,其实只有一个回调方法---onReceive,该方法在应用程序接收到发给自己广播的时候调用,所以BroadcastReceiver的使用方法也相对简单,也需要对onReceive方法进行合理重写,在适当的地方注册该BroadcastReceiver即可
注册BroadcastReceiver对象的方式有一下两种:
3.2.1 在AndroidMainfest.xml文件中声明。注册信息包裹在<receiver> </receiver>标签中,并在<intent-filter>标签内设定过滤规则。
3.2.2 在代码中创建并设置IntentFilter对象。该IntentFilter对象包含了对广播的过滤规则,然后在需要的地方调用Context.registerReceiver方法和Context.unregisterReceiver方法进行注册和取消注册。如果采用这种方式注册的话,当Context对象被销毁时,该BroadcastReceiver也就不复存在了。
4 Content Provider组件
Content Provider 和其他的应用程序组件有很大的不同,Content Provider主要用于不同的应用程序之间进行数据共享。在Android平台下,每个应用程序都有独立的内存空间,如果某一个应用程序需要使用其他应用程序的数据,就必须采用ContentProvider对象。
每个ContentProvider都继承自android.content包下的ContentProvider类,其功能就是提供自己的数据给外部应用程序使用,被提供的数据可以存储为Android文件,SQLite数据库文件或其他合法的格式。
ContentProvider提供数据及访问数据的接口,真正访问数据的是ContentResolver对象,该对象可以与ContentProvider对象进行通信,以达到共享数据的目的。
5.Intent —— 连接组件的纽带
以上 4 种基本组件中,除了 Content Provider 是通过 Content Resolver 激活外,其他 3 种组件 Activity 、 Service 和 Broadcast Receiver 都是由 Intent 异步消息激活的。
Intent 在不同的组件之间传递消息,将一个组件的请求意图传给另一个组件。因此, Intent 是包含具体请求信息的对象。
针对不同的组件, Intent 所包含的消息内容有所不同,且不同组件的激活方式也不同, 且不同类型组件有传递 Intent 的不同方式。
Intent 是一种运行时绑定( runtime binding )机制,它能够在程序运行的过程中连接两个不同的组件。通过 Intent ,你的程序可以向 Android 表到某种请求或者意愿, Android 会根据意愿的内容选择适当的组件来处理请求。
l 激活一个新的 Activity ,或者让一个现有的 Activity 执行一个新的操作,可以通过调用如下两种方法 ( 这两汇总方法需要传入的 Intent 参数称为 Activity Action Intent) :
1. Context.startActivity()
2. Activity.startActivityForResult()
l 启动一个新的服务,或者向一个已有的服务传递新的指令,可以调用如下两种方法:
1. Context.startService()
2. Context.bindService()
l 发送广播 Intent( 所有已注册的拥有与之相匹配 IntenFilter 的 BroadcastReceiv 就会被激活 ) ,可以调用如下三种方法:
1. Context.sendBroadcast()
2. Context.sendOrderBroadcast()
3. Context.sendStickBroadcast()
Intent 一旦发出, Android 都会准确找到相匹配的一个或多个 Activity 、 Service 或 BroadcastReceiver 作响应。所以,不同类型的 Intent 消息不会出现重叠, BroadcastIntent 消息只会发送给 BroadcastReceiver ,而绝不可能发送给 Activity 或 Server 。有 startActivity() 传递的消息也只可能发送给 Activity ,由 startService() 传递的 Intent 只可能发送给 Service 。