AIDL远程调用Service

与java的RMI有点类似,具体的步骤如下:

服务端

1、当自定义的数据类型时,需要实现Parcelable接口,并在类中要求有一个Parcelable.Creator类型的CREATOR  static 的final常量

package com.ccsu.training.aidl;

import android.os.Parcel;
import android.os.Parcelable;

public class UserVO implements Parcelable {
	private int account;
	private String name;
	private String pass;
	
	public UserVO(int account, String name, String pass) {
		super();
		this.account = account;
		this.name = name;
		this.pass = pass;
	}

	public UserVO() {
		super();
		// TODO Auto-generated constructor stub
	}

	public int getAccount() {
		return account;
	}

	public void setAccount(int account) {
		this.account = account;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPass() {
		return pass;
	}

	public void setPass(String pass) {
		this.pass = pass;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return account+"=="+name+"----"+pass;
	}
	
	@Override
	public int describeContents() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void writeToParcel(Parcel dest, int arg1) {
		// TODO Auto-generated method stub
		dest.writeInt(account);
		dest.writeString(name);
		dest.writeString(pass);
	}

	
	public static final Parcelable.Creator<UserVO> CREATOR = new Creator<UserVO>() {
		
		@Override
		public UserVO[] newArray(int size) {
			// TODO Auto-generated method stub
			return new UserVO[size];
		}
		@Override
		public UserVO createFromParcel(Parcel dest) {
			// TODO Auto-generated method stub
			return new UserVO(dest.readInt(),dest.readString(),dest.readString());
		}
	};
}
2、需要为此数据类型文件提供一个aidl接口,名称与类名相同UserVO.aidl文件。具体类容如:

parcelable UserVO;

3、定义暴露给客户端的接口
UserQuery.aidl 文件   要求不能有public private static final 等修饰符

package com.ccsu.training.aidl;

import com.ccsu.training.aidl.UserVO;
interface UserQuery {

	boolean checkLogin(in UserVO userVO);
	UserVO queryByAccount(int account);
}

4、定义接口的实现类RemoteUserService.java  要求 extends Stud 类  (这个类在编辑器自动生成的gen目录下UserQuery.java文件中有此抽象类extends Binder implemends UserQuery)

package com.ccsu.training.service;

import com.ccsu.training.aidl.UserQuery;
import com.ccsu.training.aidl.UserVO;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

public class RemoteUserService extends Service {

	private RemoteBinder binder ;
	@Override
	public IBinder onBind(Intent arg0) {
		return binder;
	}
	@Override
	public void onCreate() {
		super.onCreate();
		binder = new RemoteBinder();
	}
	
	<span style="background-color: rgb(255, 0, 0);">public class RemoteBinder extends UserQuery.Stub</span>{
		@Override
		public boolean checkLogin(UserVO userVO) throws RemoteException {
			return true;
		}
		@Override
		public UserVO queryByAccount(int account) throws RemoteException {
			// TODO Auto-generated method stub
			return new UserVO(922993, "xxxx", "yyyy");
		}
		
	}

}

以上为服务端的全过程

客户端

1、将自定义数据类、暴露接口复制到客户端APP

2、Activity中定义一个UserQuery 变量,并定义一个类implements ServiceConnection ,new出该类的实例。通过ServiceConnection 连接得到UserQuery 的实例可以实现访问服务端Service实现通信

package com.example.viewapp;

import com.ccsu.training.aidl.UserQuery;

import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;
import android.os.Build;

public class MainActivity extends Activity implements OnClickListener{

	private Button bindService,bindRemoteService,startIntentService;
	private UserQuery userQuery;
	private RemoteServiceConn conn = new RemoteServiceConn();
	private String remoteIntentAction = "android.intent.action.REMOTE_SERVICE";
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setContentView(R.layout.activity_main);
		initView();
		bindService();
		addListener();
	}

	private void bindService(){
		Intent remoteIntent = new Intent();
		remoteIntent.setAction(remoteIntentAction);
		bindService(remoteIntent, conn, Service.BIND_AUTO_CREATE);
		
	}
	private void initView(){
		bindService = (Button)findViewById(R.id.bindService);
		bindRemoteService = (Button)findViewById(R.id.bindRemoteService);
		startIntentService = (Button)findViewById(R.id.startIntentService);
		
	}
	private void addListener(){
		bindService.setOnClickListener(this);
		bindRemoteService.setOnClickListener(this);
		startIntentService.setOnClickListener(this);
	}

	class RemoteServiceConn implements ServiceConnection{
		@Override
		public void onServiceConnected(ComponentName componentName, IBinder binder) {
			// TODO Auto-generated method stub
			userQuery = UserQuery.Stub.asInterface(binder);
		}

		@Override
		public void onServiceDisconnected(ComponentName service) {
			// TODO Auto-generated method stub
			userQuery = null;
		}
		
	}
	@Override
	public void onClick(View view) {
		if(view.getId()==R.id.bindRemoteService){
			try {
				Toast.makeText(getApplicationContext(), userQuery.queryByAccount(99).toString(), Toast.LENGTH_LONG).show();
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}


}












你可能感兴趣的:(AIDL远程调用Service)