[Android]用AIDL生成Service

    對於用aidl生成Service,之前作過,這裏記錄一下,順便也整理一下思路。java

    一、建立aidl文件。android

    這個aidl文件必須包括包名,和用interface的形式定義方法。eclipse

    例如:IAIDLService.aidl。異步

package com.ting.androidexample.services;

interface IAIDLExampleService {
	void show();
	void function(String packageName, IBinder binder);
}

     由於我是在eclipse中開發,因此這時會在gen目錄下自動生成IAIDLExampleService.java文件。 ide

    

    二、建立AIDLService.java文件。code

    這個文件是一個Service,所以要繼承Service類,由於Service是抽象類,所以,要實現抽象的onBind方法。onBind方法的返回值是一個Binder,這個Binder是要傳給客戶端的。這個Binder要繼承自由aidl文件自動生成的IAIDLService.java類中的抽象子類Stub。而這個抽象子類中未實現的方法就是咱們在IAIDLService.aidl中定義的方法。繼承

public class AIDLService extends Service {
	
	private final IAIDLService.Stub mBinder = new IAIDLService.Stub() {

		@Override
		public void show() throws RemoteException {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void function(String packageName, IBinder binder)
				throws RemoteException {
			// TODO Auto-generated method stub
			
		}
		
	};

	@Override
	public IBinder onBind(Intent arg0) {
		return mBinder;
	}
		
}

    對於mBinder中的方法會傳給綁定它的組件,而後綁定它的組件會調用這些方法。

    三、建立與AIDLService通訊的類,好比,咱們先用Activity去調用與該Service通訊。ip

public class AIDLActivity extends Activity {
	
	private ServiceConnection conn = new ServiceConnection() {

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			
		}
		
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Intent intent = new Intent();
		bindService(intent, conn, Context.BIND_AUTO_CREATE);
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		unbindService(conn);
	}	
}

    只有執行bindService和unbindService時纔會用到AIDL這種方式。

    在執行bindService時,它的第二個參數是一個ServiceConnection實例,這個實例有兩個回調方法,onServiceConnected是服務鏈接上的回調,onServiceDisconnected是服務斷開鏈接的回調。因此說,bindService在鏈接時是異步的。對於onServiceConnected的第二個參數就是Service返回給Activity的binder。也就是靠它來通訊的。Activity能夠經過這個binder調用傳過來的方法。開發

    那麼AIDLActivity如何使用這個傳過來的Binder呢?咱們看下面的代碼。get

private ServiceConnection conn = new ServiceConnection() {

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			 mIAIDLService = IAIDLService.Stub.asInterface(service);
			 mIAIDLService.show();
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			mIAIDLService = null;
		}
		
	};

    Activity的ServiceConnection中的代碼能夠修改成上面這樣。首先獲得mIAIDLService實例,而後就能夠用mIAIDLService來執行aidl文件中定義的方法。這裏須要注意,aidl文件中定義的方法能夠是Binder,好比IAIDLService.aidl中的function方法的第二個參數就是Binder。對於Activity來講,它沒有辦法得到這個Binder傳到參數中。

    若是綁定AIDLService的是一個Service,咱們定義爲ClientService的話,而且這個 ClientService 有一些方法須要傳給AIDLService,那麼就能夠爲這個 ClientService建立IClientService.aidl文件,而且把須要的方法定義在aidl文件中。這樣,在ClientService中就能夠實例化一個它本身的Binder,而且能夠經過上面IAIDLService的function方法把這個Binder傳入。

    例如:

public class ClientService extends Service {
	
	private IAIDLService mIAIDLService;
	
	private ServiceConnection conn = new ServiceConnection() {

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			 mIAIDLService = IAIDLService.Stub.asInterface(service);
			 try {
				mIAIDLService.show();
				mIAIDLService.function(getPackageName(), mBinder);
			} catch (RemoteException e) {
				e.printStackTrace();
			}		 
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			mIAIDLService = null;
		}
		
	};
	
	private final IClientService.Stub mBinder = new IClientService.Stub() {
		
		@Override
		public void test() throws RemoteException {
			// TODO Auto-generated method stub
			
		}
	};
		
	@Override
	public void onCreate() {
		super.onCreate();
		Intent intent = new Intent();
		bindService(intent, conn, Context.BIND_AUTO_CREATE);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		unbindService(conn);
	}	

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

}

    IClientService.aidl文件爲:

package com.ting.androidexample.services;

interface IClientService {
	void test();
}
相關文章
相關標籤/搜索