Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 初級開發 >> android進程間通信:使用AIDL(2)

android進程間通信:使用AIDL(2)

編輯:初級開發

再看mAIDLActivity.Java:

vIEw plain copy to clipboard print ? 
01.package  com.styleflying.AIDL;   
02.import  android.app.Activity;   
03.import  android.content.ComponentName;   
04.import  android.content.Context;   
05.import  android.content.Intent;   
06.import  android.content.ServiceConnection;   
07.import  android.os.Bundle;   
08.import  android.os.IBinder;   
09.import  android.os.RemoteException;   
10.import  android.util.Log;   
11.import  android.view.VIEw;   
12.import  android.view.VIEw.OnClickListener;   
13.import  android.widget.Button;   
14.import  android.widget.Toast;   
15.public   class  mAIDLActivity  extends  Activity {   
16.    private   static   final  String TAG =  "AIDLActivity" ;   
17.    private  Button btnOk;   
18.    private  Button btnCancel;   
19.    private  Button btnCallBack;   
20.       
21.    private   void  Log(String str) {   
22.        Log.d(TAG, "------ "  + str +  "------" );   
23.        }   
24.       
25.    private  forActivity mCallback =  new  forActivity.Stub() {   
26.        public   void  perforMaction()  throws  RemoteException   
27.        {   
28.            Toast.makeText(mAIDLActivity.this ,  "this toast is called from service" ,  1 ).show();   
29.        }   
30.        };   
31.           
32.    forService mService;   
33.    private  ServiceConnection mConnection =  new  ServiceConnection() {   
34.        public   void  onServiceConnected(ComponentName className,   
35.                IBinder service) {   
36.            mService = forService.Stub.asInterface(service);   
37.            try  {   
38.                mService.registerTestCall(mCallback);}   
39.            catch  (RemoteException e) {   
40.                   
41.            }   
42.            }   
43.        public   void  onServiceDisconnected(ComponentName className) {   
44.            Log("disconnect service" );   
45.            mService = null ;   
46.            }   
47.        };   
48.    @Override    
49.    public   void  onCreate(Bundle icicle) {   
50.        super .onCreate(icicle);   
51.        setContentVIEw(R.layout.main);   
52.        btnOk = (Button)findVIEwById(R.id.btn_ok);   
53.        btnCancel = (Button)findVIEwById(R.id.btn_cancel);   
54.        btnCallBack = (Button)findVIEwById(R.id.btn_callback);   
55.        btnOk.setOnClickListener(new  OnClickListener() {   
56.            public   void  onClick(VIEw v) {   
57.                Bundle args = new  Bundle();   
58.                Intent intent = new  Intent(mAIDLActivity. this , mAIDLService. class );   
59.                intent.putExtras(args);   
60.                bindService(intent, mConnection, Context.BIND_AUTO_CREATE);   
61.                startService(intent);   
62.                }   
63.            });   
64.        btnCancel.setOnClickListener(new  OnClickListener() {   
65.            public   void  onClick(VIEw v) {   
66.                unbindService(mConnection);   
67.                //stopService(intent);    
68.                }   
69.            });   
70.        btnCallBack.setOnClickListener(new  OnClickListener() {   
71.               
72.            @Override    
73.            public   void  onClick(VIEw v)   
74.            {   
75.                try    
76.                {   
77.                    mService.invokCallBack();   
78.                } catch  (RemoteException e)   
79.                {   
80.                    // TODO Auto-generated catch block    
81.                    e.printStackTrace();   
82.                }   
83.            }   
84.        });   
85.        }   
86.}   
vIEw plaincopy to clipboardprint?
01.package com.styleflying.AIDL;   
02.import android.app.Activity;   
03.import android.content.ComponentName;   
04.import android.content.Context;   
05.import android.content.Intent;   
06.import android.content.ServiceConnection;   
07.import android.os.Bundle;   
08.import android.os.IBinder;   
09.import android.os.RemoteException;   
10.import android.util.Log;   
11.import android.view.VIEw;   
12.import android.view.VIEw.OnClickListener;   
13.import android.widget.Button;   
14.import android.widget.Toast;   
15.public class mAIDLActivity extends Activity {   
16.    private static final String TAG = "AIDLActivity";   
17.    private Button btnOk;   
18.    private Button btnCancel;   
19.    private Button btnCallBack;   
20.       
21.    private void Log(String str) {   
22.        Log.d(TAG, "------ " + str + "------");   
23.        }   
24.       
25.    private forActivity mCallback = new forActivity.Stub() {   
26.        public void perforMaction() throws RemoteException   
27.        {   
28.            Toast.makeText(mAIDLActivity.this, "this toast is called from service", 1).show();   
29.        }   
30.        };   
31.           
32.    forService mService;   
33.    private ServiceConnection mConnection = new ServiceConnection() {   
34.        public void onServiceConnected(ComponentName className,   
35.                IBinder service) {   
36.            mService = forService.Stub.asInterface(service);   
37.            try {   
38.                mService.registerTestCall(mCallback);}   
39.            catch (RemoteException e) {   
40.                   
41.            }   
42.            }   
43.        public void onServiceDisconnected(ComponentName className) {   
44.            Log("disconnect service");   
45.            mService = null;   
46.            }   
47.        };   
48.    @Override  
49.    public void onCreate(Bundle icicle) {   
50.        super.onCreate(icicle);   
51.        setContentVIEw(R.layout.main);   
52.        btnOk = (Button)findVIEwById(R.id.btn_ok);   
53.        btnCancel = (Button)findVIEwById(R.id.btn_cancel);   
54.        btnCallBack = (Button)findVIEwById(R.id.btn_callback);   
55.        btnOk.setOnClickListener(new OnClickListener() {   
56.            public void onClick(VIEw v) {   
57.                Bundle args = new Bundle();   
58.                Intent intent = new Intent(mAIDLActivity.this, mAIDLService.class);   
59.                intent.putExtras(args);   
60.                bindService(intent, mConnection, Context.BIND_AUTO_CREATE);   
61.                startService(intent);   
62.                }   
63.            });   
64.        btnCancel.setOnClickListener(new OnClickListener() {   
65.            public void onClick(VIEw v) {   
66.                unbindService(mConnection);   
67.                //stopService(intent);   
68.                }   
69.            });   
70.        btnCallBack.setOnClickListener(new OnClickListener() {   
71.               
72.            @Override  
73.            public void onClick(VIEw v)   
74.            {   
75.                try  
76.                {   
77.                    mService.invokCallBack();   
78.                } catch (RemoteException e)   
79.                {   
80.                    // TODO Auto-generated catch block   
81.                    e.printStackTrace();   
82.                }   
83.            }   
84.        });   
85.        }   
86.}  
package com.styleflying.AIDL;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.VIEw;
import android.view.VIEw.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class mAIDLActivity extends Activity {
 private static final String TAG = "AIDLActivity";
 private Button btnOk;
    private Button btnCancel;
    private Button btnCallBack;
    
    private void Log(String str) {
        Log.d(TAG, "------ " + str + "------");
        }
    
    private forActivity mCallback = new forActivity.Stub() {
  public void perforMaction() throws RemoteException
  {
   Toast.makeText(mAIDLActivity.this, "this toast is called from service", 1).show();
  }
  };
  
 forService mService;
 private ServiceConnection mConnection = new ServiceConnection() {
  public void onServiceConnected(ComponentName className,
    IBinder service) {
   mService = forService.Stub.asInterface(service);
   try {
    mService.registerTestCall(mCallback);}
   catch (RemoteException e) {
    
   }
   }
  public void onServiceDisconnected(ComponentName className) {
   Log("disconnect service");
   mService = null;
   }
  };
    @Override
    public void onCreate(Bundle icicle) {
     super.onCreate(icicle);
        setContentVIEw(R.layout.main);
        btnOk = (Button)findVIEwById(R.id.btn_ok);
        btnCancel = (Button)findVIEwById(R.id.btn_cancel);
        btnCallBack = (Button)findVIEwById(R.id.btn_callback);
        btnOk.setOnClickListener(new OnClickListener() {
         public void onClick(VIEw v) {
             Bundle args = new Bundle();
                Intent intent = new Intent(mAIDLActivity.this, mAIDLService.class);
                intent.putExtras(args);
                bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
                startService(intent);
                }
            });
        btnCancel.setOnClickListener(new OnClickListener() {
         public void onClick(VIEw v) {
             unbindService(mConnection);
             //stopService(intent);
             }
            });
        btnCallBack.setOnClickListener(new OnClickListener() {
   
   @Override
   public void onClick(VIEw v)
   {
    try
    {
     mService.invokCallBack();
    } catch (RemoteException e)
    {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
  });
        }
}

很短,相信大家很容易看明白。注意mConnection,它的onServiceConnected()中有一句mService = forService.Stub.asInterface(service);給mService賦值了,這個mService是一個 forService,而service是onServiceConnected()傳進來的參數,onServiceConnected()會在連接 Service的時候被系統調用,這個service參數的值來自哪裡呢?看mAIDLService.Java:

vIEw plain copy to clipboard print ? 
01.package  com.styleflying.AIDL;   
02.import  android.app.Service;   
03.import  android.content.Intent;   
04.import  android.os.IBinder;   
05.import  android.os.RemoteCallbackList;   
06.import  android.os.RemoteException;   
07.import  android.util.Log;   
08.public   class  mAIDLService  extends  Service {   
09.    private   static   final  String TAG =  "AIDLService" ;     
10.    private  forActivity callback;   
11.    private   void  Log(String str) {   
12.        Log.d(TAG, "------ "  + str +  "------" );   
13.    }   
14.    @Override    
15.    public   void  onCreate() {   
16.        Log("service create" );   
17.    }   
18.    @Override    
19.    public   void  onStart(Intent intent,  int  startId) {   
20.        Log("service start id="  + startId);   
21.    }   
22.       
23.    @Override    
24.    public  IBinder onBind(Intent t) {   
25.        Log("service on bind" );   
26.        return  mBinder;   
27.    }   
28.    @Override    
29.    public   void  onDestroy() {   
30.        Log("service on destroy" );   
31.        super .onDestroy();   
32.    }   
33.    @Override    
34.    public   boolean  onUnbind(Intent intent) {   
35.        Log("service on unbind" );   
36.        return   super .onUnbind(intent);   
37.    }   
38.    public   void  onRebind(Intent intent) {   
39.        Log("service on rebind" );   
40.        super .onRebind(intent);   
41.    }   
42.    private   final  forService.Stub mBinder =  new  forService.Stub() {   
43.        @Override    
44.        public   void  invokCallBack()  throws  RemoteException   
45.        {   
46.            callback.perforMaction();   
47.               
48.        }   
49.        @Override    
50.        public   void  registerTestCall(forActivity cb)  throws  RemoteException   
51.        {   
52.            callback = cb;   
53.               
54.        }   
55.           
56.    };   
57.}   
vIEw plaincopy to clipboardprint?
01.package com.styleflying.AIDL;   
02.import android.app.Service;   
03.import android.content.Intent;   
04.import android.os.IBinder;   
05.import android.os.RemoteCallbackList;   
06.import android.os.RemoteException;   
07.import android.util.Log;   
08.public class mAIDLService extends Service {   
09.    private static final String TAG = "AIDLService";     
10.    private forActivity callback;   
11.    private void Log(String str) {   
12.        Log.d(TAG, "------ " + str + "------");   
13.    }   
14.    @Override  
15.    public void onCreate() {   
16.        Log("service create");   
17.    }   
18.    @Override  
19.    public void onStart(Intent intent, int startId) {   
20.        Log("service start id=" + startId);   
21.    }   
22.       
23.    @Override  
24.    public IBinder onBind(Intent t) {   
25.        Log("service on bind");   
26.        return mBinder;   
27.    }   
28.    @Override  
29.    public void onDestroy() {   
30.        Log("service on destroy");   
31.        super.onDestroy();   
32.    }   
33.    @Override  
34.    public boolean onUnbind(Intent intent) {   
35.        Log("service on unbind");   
36.        return super.onUnbind(intent);   
37.    }   
38.    public void onRebind(Intent intent) {   
39.        Log("service on rebind");   
40.        super.onRebind(intent);   
41.    }   
42.    private final forService.Stub mBinder = new forService.Stub() {  
43.        @Override  
44.        public void invokCallBack() throws RemoteException   
45.        {   
46.            callback.perforMaction();   
47.               
48.        }   
49.        @Override  
50.        public void registerTestCall(forActivity cb) throws RemoteException   
51.        {   
52.            callback = cb;   
53.               
54.        }   
55.           
56.    };   
57.}  
package com.styleflying.AIDL;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;
public class mAIDLService extends Service {
    private static final String TAG = "AIDLService";  
    private forActivity callback;
    private void Log(String str) {
        Log.d(TAG, "------ " + str + "------");
    }
    @Override
    public void onCreate() {
        Log("service create");
    }
    @Override
    public void onStart(Intent intent, int startId) {
        Log("service start id=" + startId);
    }
    
    @Override
    public IBinder onBind(Intent t) {
        Log("service on bind");
        return mBinder;
    }
    @Override
    public void onDestroy() {
        Log("service on destroy");
        super.onDestroy();
    }
    @Override
    public boolean onUnbind(Intent intent) {
        Log("service on unbind");
        return super.onUnbind(intent);
    }
    public void onRebind(Intent intent) {
        Log("service on rebind");
        super.onRebind(intent);
    }
    private final forService.Stub mBinder = new forService.Stub() {
  @Override
  public void invokCallBack() throws RemoteException
  {
   callback.perforMaction();
   
  }
  @Override
  public void registerTestCall(forActivity cb) throws RemoteException
  {
   callback = cb;
   
  }
        
    };
}

注意onBind(),它的返回類型為IBinder,返回了一個mBinder,看看mBinder的定義:

    private final forService.Stub mBinder = new forService.Stub() {

        @Override
        public void invokCallBack() throws RemoteException
        {
            callback.perforMaction();
         }

        @Override
        public void registerTestCall(forActivity cb) throws RemoteException
        {
            callback = cb;

        }

       };

它是實現了我們在AIDL中定義的方法,這個mBinder最終返回給了mAIDLActivity中的mService,於是在 mAIDLActivity中可以使用mBinder中的方法了。在mAIDLActivity中也有一個類似mBinder的對象,看看定義:   

        private forActivity mCallback = new forActivity.Stub()

    {
        public void perforMaction() throws RemoteException
        {
            Toast.makeText(mAIDLActivity.this, "this toast is called from service", 1).show();
        }
      };

我們要在界面上顯示一個toast,就是在這裡實現的。這個對象,在mConnection的onServiceConnected()被調用時,通過調用mService(也就是遠程的mAIDLService中的mBinder)的registerTestCall(),傳遞給了 mAIDLService,於是在mAIDLService中可以調用perforMaction()了。

很啰嗦,只為了能把這個細節說清楚。請大家認真看,我盡量避免錯別字、混亂的大小寫和邏輯不清的語法,相信你會看明白。是不是很簡單?再啰嗦一下,做一個大致總結,我們使用AIDL是要做什麼呢:

讓Acticity(或者說一個進程/一個類?)和Service(或者說遠端進程/遠端類/對象?)獲取對方的一個Stub對象,這個對象在定義時實現了我們在AIDL中定義的方法,於是這些遠程對象中的方法可以在本地使用了。如果這種使用(通信)是單向的,比如只是Activity需要通知 Service做什麼,那麼只要Service中有一個Stub對象,並且傳給Acticity就夠了。

至於如何獲得遠程的Stub,參看上面的代碼,看mConnection、registerTestCall、onRebind,它們展示了一種方法。

另外,有時候我們可能在一個類中有多個Stub對象,它們都要給遠程交互的類的實例,這個時候可以考慮使用RemoteCallbackList<>(docs/reference/android/os/RemoteCallbackList.Html)。

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