一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Android - Android源碼學(xué)習(xí)之觀察者模式應(yīng)用及優(yōu)點(diǎn)介紹

Android源碼學(xué)習(xí)之觀察者模式應(yīng)用及優(yōu)點(diǎn)介紹

2020-12-29 15:56Android開發(fā)網(wǎng) Android

定義對(duì)象間一種一對(duì)多的依賴關(guān)系,使得當(dāng)一個(gè)對(duì)象改變狀態(tài),則所有依賴于它的對(duì)象都會(huì)得到通知并被自動(dòng)更新等等,需要了解的朋友可以參考下

觀察者模式定義
define a one-to-many dependency between objects so that when one object changes state, all its dependents aer notified and updated automatically.
定義對(duì)象間一種一對(duì)多的依賴關(guān)系,使得當(dāng)一個(gè)對(duì)象改變狀態(tài),則所有依賴于它的對(duì)象都會(huì)得到通知并被自動(dòng)更新。
Android源碼學(xué)習(xí)之觀察者模式應(yīng)用及優(yōu)點(diǎn)介紹 
如上圖所示(截取自《head first design patterns》一書),主要包括四個(gè)部分
1. subject被觀察者。是一個(gè)接口或者是抽象類,定義被觀察者必須實(shí)現(xiàn)的職責(zé),它必須能偶動(dòng)態(tài)地增加、取消觀察者,管理觀察者并通知觀察者。
2. observer觀察者。觀察者接收到消息后,即進(jìn)行update更新操作,對(duì)接收到的信息進(jìn)行處理。
3. concretesubject具體的被觀察者。定義被觀察者自己的業(yè)務(wù)邏輯,同時(shí)定義對(duì)哪些事件進(jìn)行通知。
4. concreteobserver具體觀察者。每個(gè)觀察者在接收到信息后處理的方式不同,各個(gè)觀察者有自己的處理邏輯。
觀察者模式有什么優(yōu)點(diǎn)呢
觀察者和被觀察者之間是抽象耦合的,不管是增加觀察者還是被觀察者都非常容易擴(kuò)展。
根據(jù)單一職責(zé)原則,每個(gè)類的職責(zé)是單一的,那么怎么把各個(gè)單一的職責(zé)串聯(lián)成真實(shí)的復(fù)雜的邏輯關(guān)系呢,觀察者模式可以起到橋梁作用。
觀察者模式是松耦合的典型。
在android源碼中,其中一個(gè)經(jīng)典的使用到觀察者模式的就是android控件的事件監(jiān)聽模型。
一、下面簡(jiǎn)要說明android交互事件傳輸?shù)脑O(shè)計(jì)原理和特征
交互事件,是指當(dāng)用戶通過按鍵、觸摸、滑動(dòng)等操作與應(yīng)用進(jìn)行交互時(shí)觸發(fā)的相關(guān)事件。通過android控件樹可知,交互事件是沿著控件樹自頂向下傳播的。其中android控件樹簡(jiǎn)要圖如下所示:
Android源碼學(xué)習(xí)之觀察者模式應(yīng)用及優(yōu)點(diǎn)介紹 
當(dāng)位于控件樹上層的父控件收到交互事件后,會(huì)先行判定該事件的目標(biāo)控件對(duì)象,如果該事件正是自己所需要的,則會(huì)截獲事件進(jìn)行處理,否則就嘗試將事件向下分發(fā)給對(duì)應(yīng)的子控件,并對(duì)推的逐級(jí)向下傳播事件,直至該事件被處理或者忽略。

android在view類中定義了一系列命名為view.on***的事件函數(shù)用來接收和處理各類交互事件,如通過view.onkeydown函數(shù)可以接收到用戶的按鍵操作等。每個(gè)派生自view類的子控件都可以通過重載這些事件函數(shù),來處理該控件所需的事件。

例如,如果一個(gè)控件需要處理用戶按返回鍵的操作,則可以通過重載view.onkeydown函數(shù)來實(shí)現(xiàn):

復(fù)制代碼 代碼如下:


/*
* @see android.app.activity#onkeydown(int, android.view.keyevent)
*/
@override
public boolean onkeydown(int keycode, keyevent event) {
// 監(jiān)聽和處理返回操作
if(keycode == keyevent.keycode_back) {
dosomething();
return true;
}
return false;
}


事件函數(shù)的返回值是控制事件傳播的重要手段。如果事件函數(shù)返回true,則說明該控件已經(jīng)接收并完成了該事件的處理,無須將該事件進(jìn)一步傳遞;反之,如果事件函數(shù)返回false,則說明該控件對(duì)象未能處理該事件(或雖然做過處理,但仍需要進(jìn)一步處理),需要繼續(xù)傳遞以尋找能夠處理它的控件對(duì)象。

對(duì)于容器控件viewgroup來說,它的一個(gè)職責(zé)就是將交互事件傳播到其子控件中。針對(duì)不同的事件,viewgroup可以選擇不同的傳播方式。如,如果是觸摸事件,viewgroup對(duì)象需要判定該事件發(fā)生的區(qū)域位于哪個(gè)子控件上,從而將該事件分配給該子控件進(jìn)行處理。但通過繼承的方式來進(jìn)行事件處理并不夠靈活,會(huì)導(dǎo)致系統(tǒng)中出現(xiàn)大量的子控件類型,并且各個(gè)控件的復(fù)用性都較差。因此采用“組合”來代替“繼承”。基于此思想,view類中提供了一系列配套的事件監(jiān)聽函數(shù)供開發(fā)者處理對(duì)應(yīng)事件,這就有了使用觀察者模式來完成android控件的事件監(jiān)聽模型。開發(fā)者可以構(gòu)造外部觀察者對(duì)象與控件對(duì)象的事件監(jiān)聽接口綁定,獲取事件消息。
還是以上面的按鍵事件為例,通過監(jiān)聽者進(jìn)行處理的實(shí)現(xiàn)如下所示

復(fù)制代碼 代碼如下:


final view.onkeylistener listener = new onkeylistener() {
@override
public boolean onkey(view v, int keycode, keyevent event) {
// 處理返回鍵事件
if(keycode == keyevent.keycode_back) {
dosomething();
return true;
}
return false;
}
};
。。。
muisetbutton = (button) findviewbyid(r.id.setvalue);
// 將按鈕與監(jiān)聽對(duì)象綁定
muisetbutton.setonkeylistener(listener);


通過利用外部對(duì)象來處理交互事件,其耦合性低,使每個(gè)類控件都具有更好的可復(fù)用度,無須為了處理事件而構(gòu)造新的控件。
二、現(xiàn)在開始看看源代碼是怎么進(jìn)行組織使用“觀察者模式”的
1. 看view類源代碼中的onkeylistener接口:

復(fù)制代碼 代碼如下:


/**
* interface definition for a callback to be invoked when a key event is
* dispatched to this view. the callback will be invoked before the key
* event is given to the view.
*/
public interface onkeylistener {
/**
* called when a key is dispatched to a view. this allows listeners to
* get a chance to respond before the target view.
*
* @param v the view the key has been dispatched to.
* @param keycode the code for the physical key that was pressed
* @param event the keyevent object containing full information about
* the event.
* @return true if the listener has consumed the event, false otherwise.
*/
boolean onkey(view v, int keycode, keyevent event);
}


2. 再看view類定義了私有成員monkeylistener(通過組合的方式):
private onkeylistener monkeylistener;
3. 注冊(cè)listener

復(fù)制代碼 代碼如下:


/**
* register a callback to be invoked when a key is pressed in this view.
* @param l the key listener to attach to this view
*/
public void setonkeylistener(onkeylistener l) {
monkeylistener = l;
}


4. 剩下的就交給開發(fā)者自己構(gòu)造外部觀察者對(duì)象與該按鍵的事件接口進(jìn)行綁定,獲取事件消息。
最后讓我們記住支撐“觀察者模式”的設(shè)計(jì)原則: strive for loosely coupled designs between objects that interact.

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美人与日本人xx在线视频 | 明星乱淫| bbwfreehd女厕所ved| 韩国黄色网址 | 垫底辣妹免费观看完整版 | 免费视频片在线观看大片 | 日本免费v片一二三区 | brazzersvideo欧美最新 | 久久中文字幕亚洲 | 国产精品制服丝袜白丝www | 亚洲29p| 国产激情久久久久影院小草 | 2020最新版的ab片 | 91九色porn偷拍在线 | 18young第一次| 亚洲精品中文字幕在线 | 激情六月丁香婷婷四房播 | 国产福利不卡视频在免费 | 国产日产欧产精品精品软件 | 亚洲精品在线看 | 日本高清在线看免费观看 | 日本高清视频网址 | oneday日本在线观看完整版 | 我和么公的秘密小说免费 | 亚洲日韩欧美一区二区在线 | 日韩免费在线视频观看 | 日本漫画工囗全彩内番e绅 日本伦理动漫在线观看 | 久久精品国产免费播高清无卡 | 国产精品久久久久久福利 | 日本全黄三级在线观看 | 暖暖视频免费观看视频中国.韩剧 | 韩国美女激情vip | 九九九好热在线 | 精品乱lun小说 | 精品九九视频 | 亚洲国产第一区二区香蕉日日 | 91大片淫黄大片在线天堂 | 美女下面揉出水免费视频 | 青草福利在线 | 色狼屋| 日韩精品免费一区二区三区 |