2011-11-14 152 views
2

我想知道是否有可能爲監聽器創建監聽器。例如,如果我有一個按鈕偵聽器,是否可以爲該偵聽器創建一個偵聽器,以便一旦按下按鈕,就會通知按鈕偵聽器的偵聽器。java中的監聽器如何工作

我的其他問題是,如果我有一個函數調用,它裏面有一些監聽器,這些監聽器會在函數調用返回時被銷燬。例如,我可以在程序開始時調用一個函數,該函數具有偵聽器來監聽我的主程序?

+2

爲什麼你需要一個偵聽器的偵聽器?你不能在通知按鈕偵聽器時調用方法嗎? – Tudor

+0

現在我通常不會問「爲什麼會那樣」,因爲我認爲人們有他們正確的理由,但是......爲什麼這樣呢?爲什麼不做任何第一個偵聽器所需的工作,或者在按鈕上設置了多個偵聽器,或者在偵聽器中有一個「處理程序」列表? –

+0

基本上我想要做的是添加一個jar或一個類的項目,然後只是初始化一次在開始,以儘量減少應用程序本身的變化 –

回答

2

當然可以。聽衆或「觀察者模式」非常簡單。所有的觀察者模式確實在使用接口來創建一個「契約」,讓每個人都知道某個類實現了某種方法,以便您可以確信可以在該對象上調用它。

因此,例如,你可以創建兩個接口是這樣的:

public interface OnClickListener { 
    public void onClick(); 
} 

pubic interface SomeOtherListener { 
    public void onFoo(); 
} 

一個希望「觸發」這些方法的代碼,必須對那些聽衆的參考。通常這是通過暴露一些公共方法來「設置偵聽器」來完成的。所以在某些課堂上,你會有public void setOnClickListener() { this.onClickListener = listener; }實現偵聽器的類現在可以調用setListener(this)。請注意,「this」適用於此,因爲Java中的接口可以爲您提供這種多態性。您可以將類轉換爲其實現的任何超類或接口。因此,在想要調用「onClick」的類中,所關心的是包含「onClick」的類是「onClickListener」。這就是全班同學關心的。現在,只要實現「onClick」的類對SomeOtherListener有引用(通過先前註冊),那麼onClick可以調用someOtherListener.onFoo();

因此,簡而言之(雖然它可能會使窮人在某些情況下設計)你可以在技術上擁有儘可能多的相互關聯的監聽器,只要你設置它就可以讓相關的對象/類具有對他們需要的監聽器的引用。

對不起,如果這有點混亂。此外,它很難提供更詳細的解釋,而沒有更多關於你想要做什麼的細節。

編輯

據我所知,這是不可能建立一些「包羅萬象」的Android應用中記錄每個GUI事件。由於接口方法被聲明爲必須實現的空方法,因此您必須在實現中指定您想要的精確日誌。舉例來說,每次調用setOnClickListener時,你都可以破解Android源代碼記錄某些東西,但我無法想象它會超級有用。此外,隱含在這裏,你需要爲可用的每種類型的偵聽器執行此操作。只有您實現的偵聽器才能用於任何類型的日誌記錄。例如,如果你沒有實現onTouch,那麼就沒有日誌顯示它...

+0

基本上我試圖做的是記錄android應用程序的GUI交互的所有事件,同時最小化android源代碼中的代碼更改。例如,我想向項目中添加一些jar或類,然後在android應用程序中用幾行代碼初始化它,然後它將記錄所有與GUI的事件交互。我試圖做的是從GUI獲取所有控件,並動態創建偵聽器,如果你有更好的方式做這個請分享,我試着記錄從GUI生成的所有事件。謝謝! –

2

聽衆只是一種傳播事件的方式。通常,通知偵聽器的對象具有一個保存偵聽器列表的集合。當有事件發生時,它會通知列表中的每個聽衆。

您可以創建偵聽器的偵聽器。它只是簡單的鏈接。因此,您的偵聽器將擁有一個將通知的偵聽器列表。

監聽器通常駐留在對象中,而不是函數調用。因此,您通常會創建一種在通知偵聽器的對象中添加/刪除偵聽器的方法。

+0

感謝您的迴應,基本上我試圖做的是記錄Android應用程序的GUI交互的所有事件,同時最小化Android源代碼更改。例如,我想向項目中添加一些jar或類,然後在android應用程序中用幾行代碼初始化它,然後它將記錄所有與GUI的事件交互。謝謝! –

+0

好吧有道理。 Cheers Sid –

1

您可以開始閱讀接口+策略(策略)和網橋設計模式。通常,java中的監聽器實現的方式就像一個策略,不同之處在於您有許多接口而不是單個接口。

public class MyClass{ 
public List<IListener> _listeners; 
public boolean registerListener(IListener listener){..} 
public boolean removeListener(IListener listener){...} 
public void doSomething(){ 
    if(something){ 
     //foreach listener do listener.doSomthing(); 
    } 
} 
} 

所以IListener是一個接口,你可以實現這個接口並在MyClass中註冊你的實現。

+0

基本上,我試圖做的是記錄Android應用程序的GUI交互的所有事件,同時最小化Android源代碼更改。例如,我想向項目中添加一些jar或類,然後在android應用程序中用幾行代碼初始化它,然後它將記錄所有與GUI的事件交互。我試圖做的是從GUI獲取所有控件,並動態創建偵聽器,如果你有更好的方式做這個請分享,我試着記錄從GUI生成的所有事件。謝謝! –