Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 接口回調機制詳解

Android 接口回調機制詳解

編輯:關於Android編程

在使用接口回調的時候發現了一個經常犯的錯誤,就是回調函數裡面的實現有可能是用多線程或者是異步任務去做的,這就會導致我們期望函數回調完畢去返回一個主函數的結果,實際發現是行不通的,因為如果回調是多線程的話你是無法和主函數同步的,也就是返回的數據是錯誤的,這是非常隱秘的一個錯誤。那有什麼好的方法去實現數據的線性傳遞呢?先介紹下回調機制原理。

 

回調函數

 

回調函數就是一個通過函數指針調用的函數。如果你把函數的指針(地址)作為參數傳遞給另一個函數,當這個指針被用為調用它所指向的函數時,我們就說這是回調函數。回調函數不是由該函數的實現方直接調用,而是在特定的事件或條件發生時由另外的一方調用的,用於對該事件或條件進行響應。

詳細解釋:
  客戶程序C調用服務程序S中的某個函數A,然後S又在某個時候反過來調用C中的某個函數B,對於C來說,這個B便叫做回調函數。例如Win32下的窗口過程函數就是一個典型的回調函數。一般說來,C不會自己調用B,C提供B的目的就是讓S來調用它,而且是C不得不提供。由於S並不知道C提供的B姓甚名誰,所以S會約定B的接口規范(函數原型),然後由C提前通過S的一個函數R告訴S自己將要使用B函數,這個過程稱為回調函數的注冊,R稱為注冊函數。Web Service以及Java的RMI都用到回調機制,可以訪問遠程服務器程序。
下面舉個通俗的例子:
  某天,我打電話向你請教問題,當然是個難題,你一時想不出解決方法,我又不能拿著電話在那裡傻等,於是我們約定:等你想出辦法後打手機通知我,這樣,我就掛掉電話辦其它事情去了。過了XX分鐘,我的手機響了,你興高采烈的說問題已經搞定,應該如此這般處理。故事到此結束。這個例子說明了“異步+回調”的編程模式。其中,你後來打手機告訴我結果便是一個“回調”過程;我的手機號碼必須在以前告訴你,這便是注冊回調函數;我的手機號碼應該有效並且手機能夠接收到你的呼叫,這是回調函數必須符合接口規范。
  JAVA中不允許直接操作指針,那它的回調是如何實現的呢?
  答案:它是通過接口或者內部類來實現的。
  JAVA方法回調是功能定義和功能實現分享的一種手段,是一種耦合設計思想。作為一種架構,必須有自己的運行環境,並且提供用戶的實現接口。
  1. 定義接口 Callback ,包含回調方法 callback()
  2. 在一個類Caller 中聲明一個Callback接口對象 mCallback
  3. 在程序中賦予 Caller對象的接口成員(mCallback) 一個內部類對象如
  new Callback(){
    callback(){
      //函數的具體實現
    }
  }

  這樣,在需要的時候,可用Caller對象的mCallback接口成員 調用callback()方法,完成回調。

 

回調機制在Android框架中的使用

 

在Activity中定義了很多生命周期的不同狀態要調用的方法,這些方法都是空實現,系統框架要調用,用戶也要調用來實現。
  實例(對於Android界面上Button點擊事件監聽的模擬):
    a.定義接口
    public interface OnClickListener {
      public void OnClick(Button b);
    b. 定義Button
     public class Button {
      OnClickListener listener;
      public void click() {
        listener.OnClick(this);
      }
      public void setOnClickListener(OnClickListener listener) {
        this.listener = listener;
      }
     }
    c. 將接口對象OnClickListener 賦給 Button的接口成員
    public class Activity {
      public Activity() {
      }
      public static void main(String[] args) {
        Button button = new Button();
        button.setOnClickListener(new OnClickListener(){
          @Override
          public void OnClick(Button b) {
            System.out.println(clicked);
          }
        });
        button.click(); //user click,System call button.click();
      }
    }

機制原理如上,那數據傳遞依靠接口怎麼傳遞呢?上代碼:

 

 /* 
 * @author sunglasses
 * @category 利用xUtils框架封裝get方法,IOAuthCallBack是數據接口回調,send方法裡面 有異步任務方法,
 * 傳統返回數據方法可能返回數據不正確。
 */
  public class xUtilsGet {

	public void getJson(String url,RequestParams params,final IOAuthCallBack iOAuthCallBack){

        HttpUtils http = new HttpUtils();
        http.configCurrentHttpCacheExpiry(1000 * 10);
        http.send(HttpMethod.GET, url, params, new RequestCallBack() {

			@Override
			public void onFailure(HttpException arg0, String arg1) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onSuccess(ResponseInfo info) {
				// TODO Auto-generated method stub
				iOAuthCallBack.getIOAuthCallBack(info.result);
			}
		});
	}}

我用的是xUtils開發框架然後返回數據的時候用的是接口回調,接口定義如下:

 

 

  public interface IOAuthCallBack {
	public void getIOAuthCallBack(String result);
}

上層函數定義如下:

 

 

public void getCataJson(int cityId,IOAuthCallBack iOAuthCallBack) {
		String url = http://xxxxxxx;
		RequestParams params = new RequestParams();
        params.addQueryStringParameter(currentCityId, cityId+);
		getJson(url,params,iOAuthCallBack);
	}


 

getcatajson是在你想得到數據的類中調用,然後傳入參數和接口對象,接口對象中是要對最終數據進行處理。具體機制原理如上。這樣就可以避免接口回調中的多線程數據不一致問題。 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved