Android Aidl简单实例

AIDL的作用
    由于每个应用程序都运行在自己的进程空间,并且可以从应用程序UI运行另一个服务进程,而且经常会在不同的进程间传递对象。在Android平台,一个进程通常不能访问另一个进程的内存空间,所以要想对话,需要将对象分解成操作系统可以理解的基本单元,并且有序的通过进程边界。
    通过代码来实现这个数据传输过程是冗长乏味的,Android提供了AIDL工具来处理这项工作。
 
    AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。
    AIDL IPC机制是面向接口的,像COM或Corba一样,但是更加轻量级。它是使用代理类在客户端和实现端传递数据。
  
选择AIDL的使用场合
    官方文档特别提醒我们何时使用AIDL是必要的:只有你允许客户端从不同的应用程序为了进程间的通信而去访问你的service,以及想在你的service处理多线程。
 

    如果不需要进行不同应用程序间的并发通信(IPC),you should create your interface by implementing a Binder;或者你想进行IPC,但不需要处理多线程的,则implement your interface using a Messenger。无论如何,在使用AIDL前,必须要理解如何绑定service——bindService。


在具体的case之前,先来看一下几个实例中需要用到的method

1、onServiceConnected 
Called when a connection to the Service has been established, with the IBinder of the communication channel to the Service.
当连接上service时被调用


2、bindService 
Connect to an application service, creating it if needed. This defines a dependency between your application and the service. The given conn will receive the service object when it is created and be told if it dies and restarts. The service will be considered required by the system only for as long as the calling context exists. For example, if this Context is an Activity that is stopped, the service will not be required to continue running until the Activity is resumed
连接到service,如果service不存在,则创建它


3、startService 
equest that a given application service be started. The Intent can either contain the complete class name of a specific service implementation to start, or an abstract definition through the action and other fields of the kind of service to start. If this service is not already running, it will be instantiated and started (creating a process for it if needed); if it is running then it remains running.
启动一个service;如果service没有创建,则创建之,没有启动,则启动之,startService不是嵌套的,一个stopService则会终止它


4、stopService 
Request that a given application service be stopped. If the service is not running, nothing happens. Otherwise it is stopped. Note that calls to startService() are not counted -- this stops the service no matter how many times it was started.
Note that if a stopped service still has ServiceConnection objects bound to it with the BIND_AUTO_CREATE set, it will not be destroyed until all of these bindings are removed. See the Service documentation for more details on a service's lifecycle.
停止一个service,如果所有bind到这个service都移除了,则destory这个service


5、unbindService
Disconnect from an application service. You will no longer receive calls as the service is restarted, and the service is now allowed to stop at any time.
解除绑定,如果service没有启动,则destroy


AIDL使用步骤:

1、创建.aidl file

package com.leaves.example.aidlexample;
interface example{
	int add(in int a, in int b);
}
2、添加到makefile

如果使用Eclipse,Eclipse会自动在gen目录下生成对应的.java文件


否则需要将其添加到我们的编译文件中

	LOCAL_SRC_FILES +=../example.aidl
3、Implement your interface methods - The AIDL compiler creates an interface in the Java programming language from your AIDL interface. This interface has an inner abstract class named Stub that inherits the interface (and implements a few additional methods necessary for the IPC call). You must create a class that extends YourInterface.Stub and implements the methods you declared in your .aidl file. 
实现你定义aidl接口中的内部抽象类Stub,public static abstract class Stub extends android.os.Binder implements com.cao.android.demos.binder.aidl.AIDLService
Stub类继承了Binder,并继承我们在aidl文件中定义的接口,我们需要实现接口方法,下面是我在例子中实现的Stub类

package com.leaves.example.aidlexample;

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

import com.leaves.example.aidlexample.example;

public class AIDLService extends Service{
	
	private static final String TAG = "AIDL_Service";
	
	public void onCreate() {
		Log.i(TAG,"service create");
	}
	public int onStartCommand(Intent intent, int flags, int startId)
	{
		Log.i(TAG,"service onStartCommand id=" + startId);
		return startId;
		
	}

	public IBinder onBind(Intent t) {
		Log.i(TAG,"service on bind");
		return mBinder;
	}


	public void onDestroy() {
		Log.i(TAG,"service on destroy");
		super.onDestroy();
	}


	public boolean onUnbind(Intent intent) {
		Log.i(TAG,"service on unbind");
		return super.onUnbind(intent);
	}


	public void onRebind(Intent intent) {
		Log.i(TAG,"service on rebind");
		super.onRebind(intent);
	}
	public void onStart(Intent intent, int startId) {
		Log.i(TAG,"service onStart id=" + startId);
	}
	
	private final example.Stub mBinder = new example.Stub(){
		
		@Override
		public int add(int a, int b) throws RemoteException{
			Log.i(TAG,"add a = " + a + "b = " + b);
			return a+b;
		}
	};
}
Stub翻译成中文是存根的意思,注意Stub对象是在被调用端进程,也就是服务端进程,至此,服务端aidl服务端得编码完成了,只是简单的实现两个数相加。

4、Expose your interface to clients - If you're writing a service, you should extend Service and override Service.onBind(Intent) to return an instance of your class that implements your interface. 
第四步告诉你怎么在客户端如何调用服务端得aidl描述的接口对象,doc只告诉我们需要实现Service.onBind(Intent)方法,该方法会返回一个IBinder对象到客户端,绑定服务时不是需要一个ServiceConnection对象么,在没有了解aidl用法前一直不知道它是什么作用,其实他就是用来在客户端绑定service时接收service返回的IBinder对象的,看下client的实现

package com.leaves.example.aidlexample;

import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

import com.leaves.example.aidlexample.example;

public class AIDLExample extends Activity {
	
	private static final String TAG = "AIDL_Example";
	private Button btnBind;
	private Button btnUnBind;
	private Button btnStart;
	private Button btnStop;
	private Button btnAdd;
	private EditText eNum1;
	private EditText eNum2;
	private EditText eNum3;
	
    example mService;
	private ServiceConnection mConnection = new ServiceConnection() {
		public void onServiceConnected(ComponentName className, IBinder service) {
			Log.i(TAG, "AIDLExample connect service");
			mService = example.Stub.asInterface(service);
		}


		public void onServiceDisconnected(ComponentName className) {
			Log.i(TAG, " AIDLExample disconnect service");
			mService = null;
		}
	};
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	Log.i(TAG,"AIDLExample onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_aidlexample);
        btnBind = (Button) findViewById(R.id.btn_bind);
        btnStart = (Button) findViewById(R.id.btn_start);
        btnUnBind = (Button) findViewById(R.id.btn_unbinder);
        btnStop = (Button) findViewById(R.id.btn_stop);
        btnAdd = (Button) findViewById(R.id.btn_add);
        eNum1 = (EditText) findViewById(R.id.factorOne);
        eNum2 = (EditText) findViewById(R.id.factorTwo);
        eNum3 = (EditText) findViewById(R.id.factorSum);
		Bundle args = new Bundle();
		final Intent intent = new Intent();
		intent.setAction("com.leaves.example.aidlexample.AIDLService");
		//intent.putExtras(args);
        btnBind.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				Log.i(TAG, "btnBind click");
				bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
			}
		});
        btnStart.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				Log.i(TAG, "btnStart click");
				startService(intent);
			}
		});
        btnUnBind.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				Log.i(TAG, "btnUnBind click");
				unbindService(mConnection);
			}
		});
        btnStop.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				Log.i(TAG, "btnStop click");
				stopService(intent);
			}
		});
        btnAdd.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				Log.i(TAG, "btnAdd click");
				int num1= Integer.parseInt(eNum1.getText().toString());
				int num2= Integer.parseInt(eNum2.getText().toString());
				Log.i(TAG, "num1 = " + num1 + "num2 = " + num2);
				int sum = 0;
				try {
					sum = mService.add(num1, num2);
				} catch (RemoteException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				Log.i(TAG, "result = " + sum);
				eNum3.setText(sum + "");
				
			}
		});
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_aidlexample, menu);
        return true;
    }
}

当connect上的时候获取service,这样当我们add的时候就能获取servie提供的服务了


5、在AndroidManifest.xml添加相应的service,不然的话会提示找不到service

      <service android:name="com.leaves.example.aidlexample.AIDLService">
		    <intent-filter>
			    <action android:name="com.leaves.example.aidlexample.AIDLService" />
		    </intent-filter>
	    </service>

相关log

10-24 06:44:07.322: I/AIDL_Example(909): AIDLExample onCreate
10-24 06:44:58.192: I/AIDL_Example(909): btnBind click
10-24 06:44:58.223: I/AIDL_Service(909): service create
10-24 06:44:58.223: I/AIDL_Service(909): service on bind
10-24 06:44:58.232: I/AIDL_Example(909): AIDLExample connect service
10-24 06:44:58.742: I/AIDL_Example(909): btnStart click
10-24 06:44:58.762: I/AIDL_Service(909): service onStartCommand id=1
10-24 06:45:03.242: W/KeyCharacterMap(909): No keyboard for id 0
10-24 06:45:03.242: W/KeyCharacterMap(909): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
10-24 06:45:04.787: I/AIDL_Example(909): btnAdd click
10-24 06:45:04.787: I/AIDL_Example(909): num1 = 1num2 = 3
10-24 06:45:04.793: I/AIDL_Service(909): add a = 1b = 3
10-24 06:45:04.793: I/AIDL_Example(909): result = 4



代码:

http://download.csdn.net/detail/new_abc/4682269

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值