2011年12月28日 星期三

Java - callback function(2)

現在,讓我們用callback function的概念,來實作一個程式。這支程式有四個.java,如下:

CallBackClass.java : 裡面有一個Interface叫CallBackInterface,並包含一個function,名為ShowSomething(),ShowSomething的內容在未來會被完成。

FatherClass.java : 呼叫CallBackClass中的ShowSomething()。

Main1.java : 繼承FatherClass,並implements CallBackInterface完成ShowSomething()內容,就是出現toast。

Main2.java : 繼承FatherClass,但本身不直接implements CallBackInterface,而是另外實作CallBackInterface的實體,並在此實體完成ShowSomething()內容,就是 出現AlertDialog,這和Main1是不同行為。

完整程式碼如下:

public class CallBackClass{
    public CallBackInterface myCallBackInterface;
    public interface CallBackInterface {
        //目前還不知道要做什麼事,未來會有人implements這個Interface
        //自然就要決定ShowSomething()到底要做什麼
        void ShowSomething(String title);
    }   
   
    public void startCall(String title){
        if(myCallBackInterface!=null){
            Log.d("TestCallBack","CallBackClass/startCall()");
            myCallBackInterface.ShowSomething(title);
        }
    }
}


public class FatherClass extends Activity{
    CallBackClass myCallBackClass;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.d("TestCallBack","FatherClass/onCreate()");
        super.onCreate(savedInstanceState);
        myCallBackClass = new CallBackClass();
    }
   
    public void setSomething(String title){
        Log.d("TestCallBack","FatherClass/setSomething()");
        myCallBackClass.startCall(title);
    }
}

public class Main1 extends FatherClass implements CallBackClass.CallBackInterface {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.d("TestCallBack","Main1/onCreate()");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);       
       
        super.myCallBackClass.myCallBackInterface = this;
        super.setSomething("This is Main1 Title!");
       
        Button btn = (Button) findViewById(R.id.Button01);    
        OnClickListener lis = new OnClickListener() {       
            public void onClick(View v) {
                Intent it = new Intent();
                it.setClass(Main1.this, Main2.class);   
                startActivity(it);
            }
        };
        btn.setOnClickListener(lis);   
    }

    public void ShowSomething(String title) {
        // 這個ShowSomething()是因為implements CallBackClass.CallBackInterface這個介面
        // 所以一定要完成的method
        Log.d("TestCallBack","Main1/ShowSomething()");
        Toast.makeText(this, title, Toast.LENGTH_LONG).show();
    }
}

public class Main2 extends FatherClass {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main2);
       
        CallBackClass.CallBackInterface anotherWay = new CallBackClass.CallBackInterface(){
            public void ShowSomething(String title) {
                // 這個ShowSomething()是因為用 anotherWay去實作CallBackClass.CallBackInterface這個介面
                // 所以一定要完成的method,不同於Main1,這裡改用AlertDialog
                  new AlertDialog.Builder(Main2.this)
                    .setTitle(title)
                    .setMessage("ShowSomething()相同"+"\n"+"在Main1和Main2各自有不同的行為!")
                    .show();
            }          
        };
        super.myCallBackClass.myCallBackInterface = anotherWay;
        super.setSomething("This is Main2 Title!");
    }
}

執行結果如下:
執行一開始
來到Main2,卻是AlertDialog




















以這個例子來回顧一下,我們需要那些東西來完成callback function的架構
(1)一個interface (CallBackInterface),內含一個function(ShowSomething),其內容在未來會被完成(由Main1和Main2的anotherWay完成)。

(2) super.myCallBackClass.myCallBackInterface = this; 這行是一定要的。因為必需讓這個Interface有實體的產生,這樣才知道是誰完成了ShowSomething()的內容。本例中因為是 Main1implements CallBackClass.CallBackInterface,所以this指的就是Main1。

(3) 另外super.myCallBackClass.myCallBackInterface = anotherWay;則是因為anotherWay是CallBackInterface的實體,因此當要呼叫ShowSomething時,就是到 anotherWay裡面去找ShowSomething的內容。

Main1和Main2的2種寫法,就是常常看到的事件觸發(如Button Event)的寫法。

最後附上Main1執行的log,以便清楚了解程式的流程:
D/TestCallBack( 1522): Main1/onCreate()
D/TestCallBack( 1522): FatherClass/onCreate()
D/TestCallBack( 1522): FatherClass/setSomething()
D/TestCallBack( 1522): CallBackClass/startCall()
D/TestCallBack( 1522): Main1/ShowSomething()

沒有留言:

張貼留言