2011年12月26日 星期一

Android - Pass Data (3) - Activity 和 Service 之間 (bindService, onBind)

Activity啟動Service有2種方式,1種是用Intent的startService(),另外一種是在Activity直接用bindService()啟動Service。當bindService()時利用onBind()的方式來傳遞資料。
原文請看
http://developer.android.com/reference/android/os/IBinder.html

我們需要2個.java檔來測試,一個是Activity,另一個是Service。

Activity程式碼如下:
public class Main extends Activity {
    private ServiceConnection serviceCon;
    private String mTempString = "";
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        serviceCon = new ServiceConnection() {       
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.d("TestBind","Main/onServiceConnected()");
                //利用IBinder型態的service去通訊
                ((myBinderClass) service).setTempString();
                mTempString =  ((myBinderClass) service).getTempString();
                Toast.makeText(Main.this, mTempString, Toast.LENGTH_LONG).show();
            }       
            public void onServiceDisconnected(ComponentName name) {
               
            }
        };
        Log.d("TestBind","Main/before bindService()");
        bindService(new Intent("com.test.action.myservice"), serviceCon, this.BIND_AUTO_CREATE);
    }   
}

Service程式碼如下:
public class BackgroundService extends Service {
    public String mTempString = "This is BackgroundService";

    public myBinderClass mBinder = new myBinderClass();
    @Override
    public IBinder onBind(Intent arg0) {
        Log.d("TestBind","BackgroundService/onBind()");
        return mBinder;
    }
   
    public class myBinderClass extends Binder{
        //在這裡進行Activity和Service之間的通訊
        //所以要傳遞的資料就寫在 myBinderClass裡面
        public void setTempString(){
            Log.d("TestBind","BackgroundService/setTempString()");
            mTempString = mTempString + " and it is setted by Main.";
        }
       
        public String getTempString(){
            Log.d("TestBind","BackgroundService/getTempString()");
            return mTempString;
        }
    }
}

執行結果如下:


















以下是程式流程的Log
D/TestBind( 1013): Main/before bindService()
D/TestBind( 1013): BackgroundService/onBind()
D/TestBind( 1013): Main/onServiceConnected()
D/TestBind( 1013): BackgroundService/setTempString()
D/TestBind( 1013): BackgroundService/getTempString()

從 Log可以知道,當bindService()成功後,被啟動的Service會執行onBind(),這時候會丟出一個IBinder型態的 mBinder。我們想要傳遞的東西都在mBinder裡面,然後再執行onServiceConnected(),這裡接收的一個參數是IBinder service,這個service就會是剛才丟出來的mBinder,這樣就可以在Activity去呼叫setTempString()或是 getTempString()這些你想要傳遞的東西。最後請注意,你自己寫的這個myBinderClass要繼承的是Binder,而不是 IBinder,IBinder只是一個介面interface,空空的,很多東西都是在Binder裡面才有。

沒有留言:

張貼留言