AIDL及IPC浅谈

1.IPC及AIDL产生原因:

  AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。

  在Android中,每个应用(Application)执行在它自己的进程中,无法直接调用到其他应用的资源,这也符合“沙箱”的理念。所谓沙箱原理,一般来说用在移动电话业务中,简单地说旨在部分地或全部地隔离应用程序。因此,在Android中,当一个应用被执行时,一些操作是被限制的,比如访问内存,访问传感器,等等。这样做可以最大化地保护系统,免得应用程序“为所欲为”。那我们有时需要在应用间交互,怎么办呢?于是,Android需要实现IPC协议。然而,这个协议还是有点复杂,主要因为需要实现数据管理系统(在进程或线程间传递数据)。为了暂时减缓这个“会呼吸的痛”,Android为我们实现了自己的IPC,也就是AIDL;

  AIDL是IPC的一个轻量级实现,用了对于Java开发者来说很熟悉的语法。Android也提供了一个工具,可以自动创建Stub(类构架,类骨架)

  有开发过蓝牙或者WIFI应用的朋友肯定都知道,要去操作它必须先获得一个管理类,比如WIFI的管理类是WifiManager,通过getSystemService(Context.WIFI_SERVICE)就可以得到wifi的管理权限,这个提供了很多的方法可以让用户去操作它,比如打开wifi可以调用setWifiEnabled(true)方法。那这个Manager到底做了什么工作呢?是怎样实现打开wifi的呢?其实这个Manager只是一个管理类,真正干活的另有其人,是一个叫WifiService的系统服务。在Android系统中有很多的Manager,wifi的管理类叫WifiManager,蓝牙的管理类叫BluetoothManager,但是,只要有xxxManager.java,就会有Ixxx.aidl,并且有xxxService.java。这个aidl类就是实现Manager和Service通信的桥梁。

2.安卓里面要怎么来实现这个AIDL通信呢?

  a. 常规的情况下, A 应用去激活B 应用中的组件的时候, 这实际上就是一种IPC通信的体现, 这个时候发送是Intent 就是

在做ipc通信 , intent 也是去实现 paraceable 接口的,  ipc 通信时 传递的非8 种基本数据类型都需要去实现 这个接口

  b. 进程 间 通信, 除了使用 intent 之外, 还可以使用 远程服务 调用

  c. 谷歌已经对应用中提供了 aidl的技术供应用之间进行通信

3.AIDL怎么去传输数据?

 安卓中有两个接口,一个是Serializable,另一个就是Parcelable传递的时候,其实就是将一堆数据打包,然后传输,然后再分解出来。如果某个类实现了这个接口,那么它的对象实例可以写入到Parcel中,并且能够从中恢复,并且这个类必须要有一个staticfield,并且名称要为CREATOR,这个field是某个实现了Parcelable.Creator接口的类的对象实例。 下面写一个实例:

创建model:

 public class PersonMsg implements Parcelable
{
 private String name = null;
 private int age = 0;
 
 public String getName()
 {
  return name;
 }

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

 public int getAge() 
 {
  return age;
 }

 public void setAge(int age)
 {
  this.age = age;
 }

 public int describeContents() 
 { 
  return 0;
 }
 
 public void writeToParcel(Parcel out, int flags) 
 {
  out.writeString(name);
  out.writeInt(age);
 }
 
 public static final Parcelable.Creator CREATOR = 
  new Parcelable.Creator()
  { 
   public PersonMsg createFromParcel(Parcel in) 
   {
    PersonMsg msg = new PersonMsg();
    msg.name = in.readString();
    msg.age = in.readInt(); 
    return msg;
   }

   public PersonMsg[] newArray(int size) 
   { 
    return new PersonMsg[size];
   }
  };
}
将这个model封装到intend中:

public class ActivityFrom extends Activity 
{
 private EditText nameEditText = null;
 private EditText ageEditText = null;
 private Button startButton = null;
 
   
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        nameEditText = (EditText)findViewById(R.id.name_content);
        ageEditText = (EditText)findViewById(R.id.age_content);
        startButton = (Button)findViewById(R.id.start);
        
        startButton.setOnClickListener(new View.OnClickListener()
        {
   public void onClick(View v) 
   {
    String name = nameEditText.getEditableText().toString();
    int age = Integer.valueOf(ageEditText.getEditableText().toString());
    
    Log.d("name is: ", name);
    Log.d("age is: ", age + "");
    
    PersonMsg msg = new PersonMsg();
    msg.setName(name);
    msg.setAge(age);
    
    Intent intent = new Intent();
    intent.setClass(ActivityFrom.this, ActivityTo.class);
    intent.putExtra("personmsg", msg);
    startActivity(intent);
   }
  });
    }
}
从intent中取出数据:

public class ActivityTo extends Activity
{
 private EditText nameEditText = null;
 private EditText ageEditText = null;
 private Button startButton = null;
 
   
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        nameEditText = (EditText)findViewById(R.id.name_content);
        ageEditText = (EditText)findViewById(R.id.age_content);
        startButton = (Button)findViewById(R.id.start);
        startButton.setVisibility(View.INVISIBLE);
        
        Intent intent = getIntent();
        PersonMsg msg = (PersonMsg)intent.getParcelableExtra("personmsg");
        String name = msg.getName();
        int age = msg.getAge();
        
        nameEditText.setText(name);
        ageEditText.setText(age + "");
    }
}
4.最后上一个AIDL的小demo

在远程的服务端:

service类中(注意继承IAlipayService这个类,同时在onbind这个方法中返回代理的对象):

public class AlipayService extends Service {

	private class AlipayAgent extends IAlipayService.Stub{

		@Override
		public int callPayInService(String account, float money)
				throws RemoteException {
			int result = pay(account, money);
			return result;
		}
		
	}
	
	@Override
	public IBinder onBind(Intent intent) {
		return new AlipayAgent();
	}

	@Override
	public void onCreate() {
		System.out.println("alipay 服务 创建 了 ");
		super.onCreate();
	}
	
	@Override
	public void onDestroy() {
		System.out.println("alipay 服务 销毁 了 ");
		super.onDestroy();
	}
	
	public int pay(String account, float money){
		System.out.println("alipay 支付 OK 了");
		return 1;
	}
	
}
服务接口(注意不需要修饰符):

interface IAlipayService {
	
	int callPayInService(String account, float money);
}

最后就是在mainfast文件中进行注册service:

<service android:name="com.test.alipay.AlipayService">
            <intent-filter>
                <action android:name="com.test.alipay"/>
            </intent-filter>
        </service>

  这样一个服务端的service就完成了,在写调用端的时候,注意要把服务端的 .aidl文件拷贝到本地,然后再在本地新建接口对象来调用其方法:

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	public void bindService(View v){
		
		//绑定 alipay的 服务
		
		Intent intent = new Intent();
		intent.setAction("com.test.alipay");
		bindService(intent, new MyConnection(), BIND_AUTO_CREATE);
		
	}
	
	private IAlipayService agent;
	
	private class MyConnection implements ServiceConnection{

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			
			agent = IAlipayService.Stub.asInterface(service);
			
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			
		}
		
	}
	
	public void call(View v){
		
		try {
			int result = agent.callPayInService("test", 50f);
			System.out.println(result);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}
	
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值