如果说模板模式是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"); } }
上一篇 版权所有,转载时请尊重原创显要位置注明链接,谢谢! 下一篇