Android 开发学习笔记(一)—— 四大组件
学习 Android 开发,首先脑海中要有一个大概的知识体系结构图,而 Android 的四大组件就是其中很重要的一部分。
Android 四大组件
- Activity
- Service
- Content provider
- Broadcast receiver
接下来看看他们具体都是什么
1. Activity
<1> Activity 相当于 iOS 中的 ViewController;
<2> Activity 的作用是展示用户交互,是一个屏幕界面、窗口;
<3> Activity 之间通过 Intent 跳转、通信;
<4> 每一个 Activity 都必须在 AndroidManifest.xml 配置文件中声明,否则系统将不识别也不执行该 Activity。
<5> 启动 Activity 过程:调用startActivity,该方法通过层层调用,最终会调用 ActivityStackSupervisor.java 中的 startSpecificActivityLocked。
2. Service
<1> service 就是服务,一种计算型组件;
<2> 它的作用是支持需要在后台执行的耗时操作,如下载、复杂的计算等,或者监控其他组件的运行状态;
<3> 特点:生命周期很长、没有用户交互界面、在后台运行等。
<4> 启动:调用 startService ,层层调用后,最终会调用 ActivityService.java 中的 bringUpServiceLocked。
<5> 与 Activity 只有一种运行模式(启动状态)不同,service 组件有两种状态:启动状态(started)和绑定状态(bound):
- 通过调用 startService() 启动服务,这时 service 处于启动状态, 它的内部可以做一些后台计算。尽管 service 组件用于后台耗时操作,但它本身是运行在主线程的,因此单独的耗时操作仍然需要到单独的线程中去执行;处于启动状态时的 service 生命周期与启动它的组件无关,并且可以在后台无限期运行,即使启动它的组件已经被销毁。因此,需要在完成任务后调用 stopSelf() 方法停止服务,或者由启动它的组件调用 stopService() 停止。
- 通过调用 bindService() 启动service,这时 service 处于 bound 状态,即启动 service的组件销毁,service也跟着销毁。这种状态下,可以很方便的与service 进行通信,通过调用 stopService 、 unBindService 等。
<6> service 需要在 AndroidManifest.xml 文件中生命,使用<service></service>
3. Content provider
<1> Content provider 是一种数据共享组件;
<2> 可以通过 ContentResolver 向他组件乃至其他应用共享数据,无法被用户感知;
<3> ContentProvider 使用URI(content:// ...)来唯一标识数据集。
4. Broadcast receiver
<1> 一种消息型组件,类似 iOS 中的通知?
<2> 用于在不同组件乃至不同应用之间传递消息,无法被用户感知;
<3> 静态注册和动态注册:
- 静态注册,在 AndroidManifest.xml 中进行注册广播,这种广播在应用安装时会被系统解析,不需要应用启动也可以接收到相应广播
- 动态注册,需要通过Context.registerReceiver() 来实现,并在不需要的时候通过 Context.unRegisterReceiver() 移除广播。这种广播要应用启动才能注册和接收消息,在实际开发中通过 Context 的一系列 send 方法发送消息,发送方与接收方通过接收者的<intent-filter>来实现的。
<4> 特点,动态注册广播的对象销毁后, 广播也就失效。
四大组件的相关总结
- 四大组件都需要在 AndroidManifest 文件中进行配置才能使用。
- Android 系统自带的 Content provider :
|——Browser
|——CallLog
|——Contacts
| |——Groups
| |——People
| |——Phones
| |——Photos
|——Images
| |——Thumbnails
|——MediaStore
| |——Albums
| |——Artiss
| |——Audio
| |——Genres
| |——Playlists
|——Settings
|——Video
-
Activity 生命周期:
Activity生命周期 - Activity 生命周期下的4种状态:
1. 活动状态(Activity/Running):当Activity 处于当前栈顶,此时它焦点能响应用户的操作。同一时刻有且只有一个Activity处于活动状态。
2. 暂停状态(Paused):当Activity失去焦点但仍对用户可见(如在它之上有另外一个透明的Activity或Toast、Alert时)时处于暂停状态,它仍然存活,但当系统内存极小时可能会被杀掉。
3. 停止状态(Stoped):完全被另一个Activity遮挡时处于停止状态,容易被杀掉
4. 非活动状态(Dead):Activity尚未被启动、已经被手动终止或已经被系统回收时处于Dead状态,调用finish()手动终止Activity
- Activity 生命周期7个重要方法:
/**
* 1. 当 Activity 第一次被实例化的时候系统会调用;
* 整个生命周期只调用一次;
* 通常的初始化设置:为Activity设置所有使用的布局文件;为按钮绑定监听器等静态的设置操作
*/
protected void onCreate(Bundle savedInstanceState) {
// code ...
}
/**
* 2. 当Activity可见但未获得用户焦点不能交互时系统会调用
*/
protected void onStart() {
//code ...
}
/**
* 3. 当Activity已经停止然后重新被启动时系统会调用
*/
protected void onRestart() {
//code ...
}
/**
* 4. 当Activity 可见且获得用户焦点能交互时系统会调用
*/
protected void onResume() {
//code ...
}
/**
* 5. 当系统启动另一个新的 Activity 时,在新的 Activity 启动之前被系统调用保存现有的Activity中的持久数据、停止动画等
*/
protected void onPause() {
//code ...
}
/**
* 6. 当Activity 被新的 Activity 完全覆盖不可见时被调用
*/
protected void onStop() {
//code ...
}
/**
* 7. 当Activity (用户调用finish() 或系统由于内存不足)被系统销毁时调用;
* 生命周期内只调一次;
* 用来释放onCreate()中创建的资源,如结束线程等
*/
protected void onDestroy() {
//code ...
}
- 关闭Activity后再回到这个Activity想要保持离开前的样子怎么实现呢?重写onSaveInstanceState()保存Activity被杀之前的状态(前提是用户本不想销毁这个Activity),在onPause()之前被触发,当此Activity再次被实例化时会通过onCreate(Bundle savedInstanceState)将已保存的临时状态数据传入,因为onSaveInstanceState()方法不总是被调用,触发条件为(按下Home键、按下电源键关闭屏幕、横竖屏切换情况下),代码实例如下:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (null != savedInstanceState) {
String _userID = savedInstanceState.getString("UserID");
String _UID = savedInstanceState.getString("UID");
String _password = savedInstanceState.getString("Password");
updateUserID(_userID);
updateUID(_UID);
updatePassword(_password);
}
setContentView(R.layout.activity.main);
}
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("UserID", getUserID());
outState.putString("UID", getUID());
outState.putString("Password", getPassword());
}
- BroadcastReceiver 生命周期只有十秒左右,因此如果在onReceive() 中做超过十秒的操作,就会报ANR(Application No Response)程序无响应的错误。