如果说模板模式是ANDROID框架的核心,提供了应用程序架构组件的基础,而Observer模式则提供了ANDROD架构连接件的基础,同时也是另外两个组件广播组件及内容提供者组件的实现基础,还是UI输入机制的基础。Observer模式在android应用程序及框架中普遍采用。
Observer模式也称作发布/订阅模式,实现机理是消息发布/订阅模式的事件驱动模型:消息的生产者发布事件,而使用者订阅感兴趣的事件。
我们知道Observer模式是MVC模式的基础,而 MVC模式是ANDROID框架隐藏的一个重要模式。在ANDROID框架看来ACTIVITY连同其基类ContextImpl担负着MVC模式中的控制器(Controller)角色,用来转发视图发送的控制请求,并和模型(Model)交互;而ACTIVITY绑定的视图(DecorView),在MVC模式中也起到视图(VIEW)角色,DecorView是ACTIVITY的主视图,其它子视图或控件都由ACTIVITY通过读取应用程序的布局文件(XML格式)生成,并组合成视图树,实现视图的布局(视图采用了组合模式组合成视图树)。而框架的每一个服务及其产生的数据则提供了MVC模型(Model)的角色。而每个服务通过ContextImpl中登记的本地服务管理对象进行控制,视图也通过控制器(ContextImpl)登记对模型事件的监听,控制器本身也可以登记为监听对象。本地服务管理对象本身或者应用程序视图通过本地服务管理对象(Controller)向模型发出请求消息和服务(Model)交互,服务产生的数据发生变化时,通过Observer模式(广播或INTENT)通知视图和控制器。在MVC模式中视图是观察者Observer,视图通过组合模式组合成视图树,控制器担当视图和模型的中介者,因此这里的MVC模式是采用Observer模式、组合模式、中介模式的复合模式。
采用MVC模式可以简化应用程序的开发,而通过框架提供模型及控制器的实现则使应用程序的开发更加容易。应用程序只需继承控制器(ACTIVITY)和实现回调接口、编写VIEW的布局XML文件、提供用到的资源文件、注册对模型的监听事件、编写与模型提供数据的接口(ANDROID又是推荐采用Adapter模式实现与各种数据源接口,ANDROID为此针对数据库提供了SimpleCursorAdapter类)等五个任务就可完成应用程序的开发。而业务逻辑及数据提供、转发视图的控制请求都交给框架处理好了,应用开发如此简单。下面看一个ACTIVITY的具体例子。
private BroadcastReceiver mScanListener = new BroadcastReceiver() {//实例化一个广播对象
@Override
public void onReceive(Context context, Intent intent) {//实现广播接收回调接口
MusicUtils.setSpinnerState(AlbumBrowserActivity.this);
mReScanHandler.sendEmptyMessage(0);
if (intent.getAction().equals(Intent.ACTION_MEDIA_UNMOUNTED)) {
MusicUtils.clearAlbumArtCache();
}
}
};
public class MyActivity extends Activity implements OnItemClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter f = new IntentFilter();
f.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
f.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
f.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
f.addDataScheme("file");
registerReceiver(mScanListener, f);//注册对模型的广播监听事件
setContentView(R.layout.media_picker_activity);//读取布局文件生成视图树
Cursor c = getContentResolver().query(Settings.System.CONTENT_URI, null, null, null, null);//首先通过控制器获得数据源的指针
ListAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1,
c,
new String[] {People.NAME} ,
new int[] {android.R.id.text1});
setListAdapter(adapter);//采用Adapter模式设置与数据源的接口
getListView().setOnItemClickListener(this);//设置视图控件的监听者,控制器监听
}
public void onItemClick(AdapterView parent, View view, int position, long id) {//视图监听事件的回调接口
Intent dummyIntent = new Intent(this, ListSimple.class);
startActivity(dummyIntent);
}
在ContextImpl中采用静态代码块的方法把总共34个系统服务管理对象预先登记到ContextImpl的CACHE中,视图或控制器对象通过getSystemService接口统一从cache获取服务管理对象,实现与模型的交互。由于这种方式实现了对象只在包装载时实例化一次,并登记到cache,因此能够实现提高获取系统服务管理对象的速度的目的。
private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
new HashMap<String, ServiceFetcher>();//实例化保存fetcher对象的HashMap,fetcher对象实际完成读取本地服务管理对象的目的。
private static void registerService(String serviceName, ServiceFetcher fetcher) {
if (!(fetcher instanceof StaticServiceFetcher)) {
fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
}
SYSTEM_SERVICE_MAP.put(serviceName, fetcher);//根据服务名字把fetcher对象放到HashMap中
}
static {
registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
public Object getService(ContextImpl ctx) {
return AccessibilityManager.getInstance(ctx);
}});//把一个fetcher对象登记到ACCESSIBILITY_SERVICE服务名字对应的HashMap中,并覆盖getService函数
registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
IAccountManager service = IAccountManager.Stub.asInterface(b);
return new AccountManager(ctx, service);
}});//把一个fetcher对象登记到ACCOUNT_SERVICE服务名字对应的HashMap中,并实现其createService接口。
…
}
static class ServiceFetcher {
public Object getService(ContextImpl ctx) {
ArrayList<Object> cache = ctx.mServiceCache;
Object service;
synchronized (cache) {
if (cache.size() == 0) {
for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
cache.add(null);
}
} else {
service = cache.get(mContextCacheIndex);//从cache中获取服务
if (service != null) {
return service;
}
}
service = createService(ctx);// 在cache中获取不到则实例化服务管理对象。
cache.set(mContextCacheIndex, service);//重新把新创建的服务管理对象放到cache中,供下次使用。
return service;
}
}
}
@Override
public Object getSystemService(String name) {//获取本地服务管理对象统一接口
ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
return fetcher == null ? null : fetcher.getService(this);//通过fetcher的getService接口获取本地服务管理对象。
}
框架中Observer模式大量采用,包括JNI向JAVA层发送通知等。见android_media_MediaPlayer.cpp文件
static void android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
{
LOGV("native_setup");
sp<MediaPlayer> mp = new MediaPlayer();
sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this);
mp->setListener(listener);// 登记C++层媒体播放器的监听器为一个JNI对象。
}
void JNIMediaPlayerListener::notify(int msg, int ext1, int ext2, const Parcel *obj)
{
JNIEnv *env = AndroidRuntime::getJNIEnv();
if (obj && obj->dataSize() > 0) {
…
env->CallStaticVoidMethod(mClass, fields.post_event, mObject,
msg, ext1, ext2, jArray);//在这里JNI监听器对象转发播放器产生的事件
}
}
void MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj)
{
sp<MediaPlayerListener> listener = mListener;
if ((listener != 0) && send) {
listener->notify(msg, ext1, ext2, obj); //播放器产生事件的回调接口在这里向JNI listener对象发送通知。
LOGV("back from callback");
}
}