Android介面回撥傳遞資料
回撥函式就是一個通過函式指標呼叫的函式。如果你把函式的指標(地址)作為引數傳遞給另一個函式,當這個指標被用為呼叫它所指向的函式時,我們就說這是回撥函式。回撥函式不是由該函式的實現方直接呼叫,而是在特定的事件或條件發生時由另外的一方呼叫的,用於對該事件或條件進行響應。
Java 中沒有指標的概念,通過介面和內部類的方式實現回撥的功能:
1. 定義介面 Callback ,包含回撥方法 callback()
2. 在一個類Caller 中宣告一個Callback介面物件 mCallback
3. 在程式中賦予 Caller物件的介面成員(mCallback) 一個內部類物件如
new Callback(){
callback(){
//函式的具體實現
}
這樣,在需要的時候,可用Caller物件的mCallback介面成員 呼叫callback()方法,完成回撥.
二、回撥機制在 Android框架 監聽使用者介面操作中的作用
Android事件偵聽器是檢視View類的介面,包含一個單獨的回撥方法。這些方法將在檢視中註冊的偵聽器被使用者介面操作觸發時由Android框架呼叫。回撥方法被包含在Android事件偵聽器介面中:
例如,Android 的view 物件都含有一個命名為 OnClickListener 介面成員變數,使用者的點選操作都會交給 OnClickListener的 OnClick() 方法進行處理。
開發者若需要對點選事件做處理,可以定義一個 OnClickListener 介面物件,賦給需要被點選的 view的介面成員變數OnClickListener,一般是用 view 的setOnClickListener() 函式來完成這一操作。
當有使用者點選事件時,系統就會回撥被點選view的OnClickListener介面成員的OnClick()方法。
例項(對於Android介面上Button點選事件監聽的模擬):
1.定義介面
public interface OnClickListener {
public void OnClick(Button b);
}
2. 定義Button
public class Button {
OnClickListener listener;
public void click() {
listener.OnClick(this);
}
public void setOnClickListener(OnClickListener listener) {
this.listener = listener;
}
}
3. 將介面物件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();
}
}
三、利用回撥機制傳遞資料並重新整理U
示例:用一個類中的方法下載一張圖片,通過回撥函式返回一個Bitmap物件,主程式例項化這個類並呼叫它的回撥函式即可
1、定義一個Caller類,裡面建立一個藉口類OnCallListener
package com.example.interfacecallback;
import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Looper;
public class Caller {
public Caller() {
// TODO 自動生成的建構函式存根
}
public interface OnCallListener {
public void onCall(Bitmap bitmap);
}
public void setOnCallListener(final OnCallListener listener) {
new Thread(new Runnable() {
@Override
public void run() {
// TODO 自動生成的方法存根
Looper.prepare(); // 類中本身沒有沒有Looper物件,需要線上程中建立
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet("http://www.baidu.com/img/bdlogo.gif");
Bitmap bitmap = null;
try {
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() == 200) {
byte[] data = EntityUtils.toByteArray(response
.getEntity());
bitmap = BitmapFactory.decodeByteArray(data, 0,
data.length);
}
} catch (ClientProtocolException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
} catch (IOException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
listener.onCall(bitmap);
Looper.loop(); // 迴圈訊息佇列
}
}).start();
}
}
主程式MainActivity實現介面回撥
package
com.example.interfacecallback;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.Toast;
import com.example.interfacecallback.Caller.OnCallListener;
public class MainActivity extends Activity {
private ImageView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (ImageView) findViewById(R.id.tv);
Caller caller = new Caller();
caller.setOnCallListener(new OnCallListener() {
@Override
public void onCall(Bitmap bitmap) {
// 在沒有網路的情況下bitmap為空
if (bitmap == null) {
Toast.makeText(MainActivity.this, "連線網路失敗",
Toast.LENGTH_SHORT).show();
} else {
tv.setImageBitmap(bitmap);
}
}
});
}
}
注意:新增網路許可權
<uses-permission android:name="android.permission.INTERNET"/>