Android四大组件
一、简介
Activity负责UI元素的加载与页面之间的跳转,代表一个页面单元。Service负责与UI无关的工作,如在后台执行耗时操作等。ContentProvider负责存储、共享数据,使得数据可以在多个应用之间共享。Broadcast则是在各个组件、应用之间通信,简化Android开发中的通信问题。Intent将它们联接在一起,彼此之间却几乎没有耦合。应用中的某一项功能可能是由来自很多应用的若干个组件共同完成的。各个Android应用只有明确的组件边界,而不再有明确的应用边界。Android就是高度组件化、可复用的系统。
二、Activity
1、Activity加载指定的布局文件来显示各种UI元素,并为他们设置事件处理函数;Activity还可以在不同的Activity之间跳转,将不同的页面串联在一起,共同完成特定的操作流程。
2、默认的activity:
<intent-filter>
<action android:name=”android.intent.action.MAIN”/>
<category android:name=”android.intent.category.LAUNCHER”/>
</intent-filter>
3、生命周期
onCreate():第一次被创建,完成初始化操作,如设置布局、初始化视图、绑定事件。
onStart():onCreate()之后调用,可见之前调用。
onResume():变为可见的时候调用,渲染视图。
onPause():启动或恢复另一个activity时,从可见变为不可见时调用,释放资源,保存数据。
onStop():完全不可见的时候调用。
onDestroy():被销毁之前调用
onRestart():由停止状态重新变为运行状态。onStop-->onRestart()-->onStart()
4、构成
视图会被设置给一个Window类,Window中含有一个Decor View,Decor View是整个窗口的顶级视图。开发人员设置的布局在Decor View的mContentParent布局中。Android内置了一些系统布局xml,我们在xml定义的视图会被设置到系统布局的特定结点下,形成整个Decor View。如图所示,PhoneWindow是Window的实现类。
5、启动模式
在注册时设置:
<activity
android:launchMode=”singleTask”>
·standard:可以被多次实例化,每个实例都会处理一个Intent对象。
·singleTop:如果在栈顶就重用在栈顶的实例,并调用他的onNewIntent()将Intent对象传递到实例中。如果不在栈顶就创建一个新的实例。
·singleTask:在一个任务栈(应用)里只能有一个实例。如果没有就新建一个到栈顶,如果已经存在但是不在栈顶,则销毁他上面的所有activity使他处于栈顶,同时回调onNewIntent()。(不同的应用有自己的任务栈)
·singleInstance:在一个独立的任务中开启,系统中有且只有一个实例,调用onNewIntent()。
6、fragment:嵌套在activity中使用,更大粒度的UI单元。
三、Service
Service执行在UI线程中,所以不要在Service中执行耗时操作除非开了子线程。当某个应用进程被杀掉时所有依赖于他的Service也会停止运行。每个服务只存在一个实例。记得注册。
1、生命周期
onCreate()、onStartCommand()、onDestroy()。
一旦调用了startService(),服务开始启动。首次创建调用onCreate(),然后回调onStartCommand()。直到stopService()或者stopSelf()被调用。每调用一次startService()就执行一次onStartCommand()。但是只需要调用一个stopService()或者stopSelf(),服务就会停止。
2、普通Service
public class MyService extends Service{
public int OnStartCommand(Intent intent,int flags,int startID)
{}
private void doMyJob(Intent intent)
{
//执行耗时操作
new Thread()
{
public void run(){}
}.start();
}
public IBinder onBind(Intent intent){return null;}
}
3、IntentService
将用户的请求执行在一个子线程中,执行完毕后调用stopSelf()自我销毁。适用于完成短期耗时任务。
public class MyIntentService extends IntentService{
MyIntentService()
{super(MyIntentService.class.getName());}
protected void onHandleIntent(Intent intent){
//执行耗时操作
}
}
4、前台Service
一直保持运行状态可以运行在前台。
startForeground( , );
四、Broadcast
一个广播可以有任意个接受者。广播机制是发布——订阅模式,也就是观察者模式。发送方不关心接收方是否收到,也不关心接收方如何处理数据,接收双方完全解耦合。
1、普通广播
异步,不能将处理结果传递给下一个接收者,也不能终止广播intent的传播。接收器的执行顺序不确定。
定义接收器:
public class MyBroadcastReceiver extends BroadcastReceiver{
public void onReceive(Context context,Intent intent)
{
Toast……
}
}
静态注册:
<receiver android:name=”.broadcast.myBroadcastReceiver”>
<intent-filter> <action android:name=””/>
</intent-filter>
</receiver>
动态注册:
private void registerMyBroadcast()
{
registerReceiver(new MyBroadcastReceiver(),new IntentFilter(...ACTION));
}
发送广播:
sendBroadcast(new Intent(xxxACTION));
2、有序广播
接收器按照优先级依次执行,通过intent-filter中的android:priority设置,数值越大优先级越高。可以使用setResult()、getResult()来传给下一个、取得上一个结构。可以用abortBroadcast()来终止广播的传送。
3、本地广播(21版)
只在应用的进程内使用广播。使用LocalBroadcastManager getInstance(Context context)调用函数。建议在不需要其他进程接收广播的情况下使用本地广播。
注册:registerReceiver(receiver,intentFilter);
注销:unregisterReceiver(receiver);
发送异步广播:sendBroadcast(new Intent(xxx));
发送同步广播:sendBroadcastSync(new Intent());
4、sticky广播
广播会一直滞留,保留最后一条广播并一直保留下去。即使有接收器处理了该广播,其他匹配的接收器被注册时仍会接收这条广播。
发送:Context.sendStickyBroadcast()
权限:<uses-permission android:name=”android.permission.BROADCAST_STICKY”>
五、ContentProvider
其他应用可以通过ContentProvider对应用中的数据进行增删改查。统一了数据的访问方式,对SQLiteOpenHelper的进一步封装,通过Uri映射来判断选择操作数据库中的哪个表。
URI:
schema + authority + path + [id]
content:// 包名 表名 字段名(*任意字符,#任意数字)
字符串转换成URI:
Uri uri=Uri.parse(“”);
1.覆盖insert、query、update、delete、getType()等函数。
static UriMatcher uriMatcher=new UriMatcher(UriMatcher.NO_MATCH);
static
{
uriMatcher.addUri(AUTHORITY,”userinfo”,USER_INFOS);
…………
}
public String getType(Uri uri)
{
switch(uriMatcher.match(uri))
{
case USER_INFOS:
return content_type;
}
}
public Uri insert(Uri uri,ContentValues values)
{
Uri newUri=null;
switch(uriMatcher.match(uri))
{
case USER_INFOS:
newID=mDatabase.insert(DBHelper.TABLE_USER_INFO,null,values);
newUri=Uri.parse(CONTENT+AUTHORITY+”/”+DBHelper.TABLE_USER_INFO+”/”+newID);
break;
}
}
public Cursor query(………………)
{
Cursor c=null;
switch(uriMatcher.match(uri))
{
case USER_INFOS:
c=mDatabase.query(……);
break;
}
return c;
}
DBhelper类略。
2.注册
<provider android:name=”.provider.UserInfoProvider”
android:authorities=”包名”/>
3.使用
getContentResolver().insert(XXProvider.XXuri,xxx);