我们知道,Android应用通常由一个或多个基本组件组成。其中,最基本的四个组件分别就是Activity、Service、BroadcastReceiver以及ContentProvider。下面我来分享一下自己对这四个基本组件的认识。
Activity
Service
BroadcastReceiver
ContentProvider
Activity是Android应用中负责与用户交互的组件——大致上可以把它看作是Swing编程中的JFrame控件。不过它与JFrame的区别在于:JFrame本身可以设置布局管理器,不断地向JFrame中添加控件,但Activity只能通过setContentView(View)来显示指定的组件。
一般一个Android应用是由多个activity组成的,这多个activity之间可以进行相互跳转。例如,按下一个Button按钮后,可能会跳转到其他的activity,与网页跳转稍微有点不一样的是,activity之间的跳转有可能返回值。例如,从activity A跳转到activity B,那么当activity B运行结束时,有可能会给activity A一个返回值。这样做在很多时候是相当方便的。
Activity为Android应用提供了可视化用户界面,如果该Android应用需要多个用户界面,那么这个Android应用将会包含多个Activity,多个Activity组成Activity栈,当前活动的Activity位于栈顶。
接下来,我们来说一下其生命周期。关于这一点,我之前写过类似的文章,详见拙作:Android之浅谈activity生命周期
需要注意的是,Android中四大组件在使用前都需要注册。Android应用中每一个Activity都必须要在AndroidManifest.xml配置文件中声明,否则系统将不识别也不执行该Activity,如:
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
intent-filter>
activity>
四种启动模式(LaunchMode)
先来看实现的代码:
<activity
android:name=".SecondActivity"
android:launchMode="singleInstance"
//四种启动模式都需要在清单文件下的Activity节点下配置,如果不配置,则默认标准standard开启activity
>
activity>
下面是对其参数进行介绍:
standard:
默认模式,每次激活Activity时都会创建Activity实例,并放入任务栈中
singleTop:
如果在任务的栈顶正好存在该Activity,就会重用该实例(会调用实例的onNewIntent()),否则就会创建新的实例放入栈顶(注:即使栈中已经存在该Activity的实例,只要不在栈顶,都会创建实例)
singleTask:
如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的onNewIntent())。重用时,会让该实例回到栈顶,因此在它上面的实例将会被转移出栈,如果栈中不存在该示例,将会创建新的实例放入栈中
singleInstance:
在一个新栈中创建该Activity实例,并让多个应用共享该栈中的该Activity实例,一旦该模式的Activity实例已经存在于某个栈中,任何应用在激活该Activity时都会重用该栈中的实例(会调用实例的onNewIntent())。其效果相当于多个应用共享一个应用,不管谁激活该Activity都会进入同一个应用中
Service 与Activity的地位是并列的,它也代表一个单独的Android组件。Service 与Activity的区别在于:Service 通常位于后台运行,它一般不需要与用户交互,因此Service 组件没有图形用户界面。
与Activity组件需要继承Activity基类相似,Service 组件需要继承Service 基类。一个Service 组件被运行起来之后,它将拥有自己独立的生命周期,Service 组件通常用于为其他组件提供后台服务或监控其他组件的运行状态。
下面介绍关于Service 生命周期的方法:
同样地,需要在AndroidManifest.xml文件中配置该Service,如:
<service android:name=".FirstService">
service>
下面介绍一下Android系统中运行Service的两种方式:
无论通过哪种方法启动Service,都可以用stopService()方法将其关闭
如果大家想对Service有更深的了解的话,在这里推荐一篇博客,里面有对Service详细的讲解:解读Android之Service(1)基础知识
BroadcastReceiver是Android应用中另一个重要的组件,顾名思义,BroadcastReceiver代表广播消息接收器。从代码实现的角度看,BroadcastReceiver非常类似于事件编程中的监听器。与普通事件监听器不同的是,普通事件监听器监听的事件源是程序中的对象;而BroadcastReceiver监听的事件源是Android应用中的其他组件。
由于BroadcastReceiver本质上属于一个监听器,因此实现BroadcastReceiver的方法也十分简单,只要重写:
public void onReceive(Context context,Intent intent)方法即可
注意: onReceive方法必须在10秒内完成,如果没有完成,则抛“Application No Response”当广播接收者onReceive方法需要执行很长时间时,最好将此耗时工作通过Intent发送给Service,由Service完成,并且不能使用子线程解决,因为BroadcastReceiver是接收到广播后才创建的,并且生命周期很短,因此子线程可能在没有执行完就已经被杀死了。
此时,如果有通过Context.sendBroadcast(Intent intent)或Context.sendOrderedBroadcast(Intent intent)发送的意图,通过这个语句,能够广播给所有满足条件的组件,比如intent设置了action=”com.xiazdong”,则所有在AndroidManifest.xml中设置过的广播接收者都能够接收到广播。
对于发送广播的一方,通常就是调用Context.sendBroadcast()的程序,而广播接收者就是继承BroadcastReceiver的程序;
通常广播发送方都是通过隐式意图,这样才能发送给多人;
广播发送方分为普通广播和有序广播;
同步广播:发送方发出后,几乎同时到达多个广播接收者处,某个接收者不能接收到广播后进行一番处理后传给下一个接收者,并且无法终止广播继续传播;Context.sendBroadcast(intent);
有序广播:广播接收者需要提前设置优先级,优先级高的先接收到广播,优先级数值为-1000~1000,在AndroidManifest.xml的设置;比如存在3个广播接收者A、B、C,优先级A>B>C,因此A最先收到广播,当A收到广播后,可以向广播中添加一些数据给下一个接收者(intent.putExtra()),或者终止广播(abortBroadcast());Context.sendOrderedBroadcast(intent);
在这里也推荐给大家我学习BroadcastReceiver的博客: Android入门:广播发送者与广播接收者
对于Android应用而言,它们必须相互独立,各自运行在自己的进程中,如果这些Android应用之间需要实现实时的数据交换——例如,我们开发了一个发送短信的程序,当发送短信时需要从联系人管理应用中读取指定联系人的数据——这就需要多个应用程序之间进行数据交换。
Android系统为这种跨应用的数据交换提供了一个标准:ContentProvider。通常与ContentProvider结合使用的是ContentResolver,一个应用程序使用ContentProvider暴露自己的数据,而另一个应用程序则通过ContentResolver来访问数据。
当用户实现自己的ContentProvider时,同时也需要实现如下的抽象方法:
同样地,这个组件在使用之前也需要进行配置,如:
<provider
android:authorities=".FirstProvider"
android:name="org.crazyit.providers.firstprovider"
android:exported="true">
provider>
事实上,当其他应用通过getContentResolver()获取ContentResolver对象来调用query()、insert()、update()、和delete()方法执行数据访问时,实际上就是通过调用指定Uri对应的ContentProvider的query()、insert()、update()、和delete()方法。
这里简单介绍ContentProvider中的Uri:
content://org.crazyit.providers.firstprovider/words
其中可分为三个部分: