Android之AIDL使用

本文详细解析了Android中实现进程间通信的技术AIDL,包括其原理、使用场景以及与Service创建方法(startService和bindService)的关系。通过实例展示了如何在Activity与Service之间进行绑定并获取数据。

    学习中总是有那么一座大山挡在你的面前,你是视而不见,还是绕着山边的路走? 今天就来彻底翻阅挡在我面前的一座大山--AIDL
在Android中,如果我们需要在不同进程间实现通信,就需要用到AIDL技术去完成。
    AIDL(Android Interface Definition Language)是一种接口定义语言,编译器通过*.aidl文件的描述信息生成符合通信协议的Java代码,我们无需自己去写这段繁杂的代码,只需要在需要的时候调用即可,通过这种方式我们就可以完成进程间的通信工作。
    为什么我们要学习AIDL呢?这就要了解Android中Service创建的两种方法: startService或者bindService
   我们知道,服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。这两个方法都 可以启动Service,但是它们的使用场合有所不同。使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服 务仍然运行。使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的 特点。
    如果打算采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。
    如果打算采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()-->onDestroy()方法。
    好了,说了这么多,我们还是来看一个例子吧!

   下面的一个例子非常简单,就是完成Activity与Service的绑定,点击Activity上的Button,获得颜色名称。

    我首先在服务端定义了AIDL接口

    

package com.mdx.server;

interface ICat
{
	String getColor();
	
}
    定义好上面的AIDL接口之后,ADT工具就会在gen/com/mdx/server目录下生成一个ICat.java接口文件,在该接口文件中包含了一个 Stub内 部类,该内部类实现了IBinder ICat 接口,这个Stub类将会作为Service的回调类。它实现了IBinder接口,所以可以作为Service的OnBin的()接口的返回值。

    定义好AIDL接口之后,我们就可以定义一个Service实现类了。这个Service中的OnBind()方法所返回的IBinder对象就是那个ICat.Stub的子类的实例。

    先看一下服务端的目录结构:

    

  服务端代码:

package com.mdx.server;

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

import com.mdx.server.ICat.Stub;


public class MyMusicService extends Service {

	private MyBinder myBinder;
	
	public class MyBinder extends Stub
	{
		@Override
		public String getColor() throws RemoteException {
			// TODO Auto-generated method stub
			
			return "yellow";
		}
		
	}

	@Override
	public IBinder onBind(Intent intent) {
		Log.i("MYSERVICE", "MyService is onBind!");

		return myBinder;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		
		myBinder = new MyBinder();
		Log.i("MYSERVICE", "MyService is onCreate!");

	}

	
}

记得在mainest中注册Service。


客户端目录结构:


    客户端绑定远程Service的步骤分为两步:

  • 创建ServiceConnetion对象
  • 以ServiceConnection对象作为参数,调用Context的bindService()方法绑定远程Service

绑定远程Service的ServiceConnection并不能直接获取Service的OnBind()方法所返回的对象,它只能返回OnBind()方法所返回的对象的代理


客户端代码如下:

package com.paad.client;

import android.app.Activity;
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.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.mdx.server.ICat;

public class MyActivity extends Activity {

	TextView asyncTextView;
	ProgressBar asyncProgress;
	Button start;

	private ICat myAidl;
	// Handles the connection between the service and activity
	private ServiceConnection mConnection = new ServiceConnection() {

		public void onServiceConnected(ComponentName className, IBinder service) {
			// Called when the connection is made.
			Log.i("MYACTIVITY", "OnserviceConnected() called");
			myAidl = ICat.Stub.asInterface(service);

		}

		public void onServiceDisconnected(ComponentName className) {
			// Received when the service unexpectedly disconnects.
			Log.i("MYACTIVITY", "onServiceDisconnected() called");
		}
	};

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

		asyncTextView = (TextView) findViewById(R.id.asyncTextView);
		// asyncProgress = (ProgressBar) findViewById(R.id.asyncProgress);
		start = (Button) findViewById(R.id.start);

		Intent bindIntent = new Intent();
		bindIntent.setAction("android.intent.action.AIDLService");
		bindService(bindIntent, mConnection, Service.BIND_AUTO_CREATE);

		start.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub

				String ss;
				try {
					ss = myAidl.getColor();
					asyncTextView.setText("颜色是:" + ss);
				} catch (RemoteException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		});
	}

}

点击按钮,可以看到一下结果:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值