AIDL
AIDL:Android interface define language,用与实现Android应用之间的通信。
1.服务端
Android进程之间不能共享内存,进城之间要进行通信(IPC)就要使用AIDL。
在服务端的manifest0.xml文件中添加service
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.aidl.server"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<service android:name="RemoteService">
<intent-filter >
<action android:name="com.example.aidl.webpage"/>
</intent-filter>
</service>
</application>
</manifest>
可以看到服务端的包名为:com.braincol.aidl.server,且该服务端只需一个service组件提供AIDL服务,service组件的名称为RemoteService,这是待会要实现的Service子类。其中<action android:name="com.braincol.aidl.remote.webpage"/> 指定了action名称为"com.braincol.aidl.remote.webpage", 客户端会通过该action的名称来找到并连接该服务端。1.2创建AIDL文件
在包com.example.aidl.server;中创建AIDL文件,eclipse会自动在/gen目录下对应的包中生成对应的RemoteWebpage.java文件
package com.example.aidl.server;
interface RemoteWebpage{
String getCurrentPageUrl() ;
}
1.3编写Java实现
编写Java实现RemoteService.Java继承RemoteWebpage中的内部类Stub,实现在AIDL文件中声明的方法getCurrentPageUrl()。
package com.example.aidl.server;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class RemoteService extends Service {
private final static String TAG = "RemoteService" ;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.i(TAG, "onBind") ;
return new MyBinder();
}
private class MyBinder extends RemoteWebpage.Stub
{
@Override
public String getCurrentPageUrl() throws RemoteException {
// TODO Auto-generated method stub
return "www.baidu.com";
}
}
}
总结
1. 创建.aidl文件:
该文件(YourInterface.aidl)定义了客户端可用的方法和数据的接口
2. 实现这个接口:
Android SDK将会根据你的.aidl文件产生AIDL接口。生成的接口包含一个名为Stub的抽象内部类,该类声明了所有.aidl中描述的方法,你必须在代码里继承该Stub类并且实 现.aidl中定义的方法。
3.向客户端公开服务端的接口:
实现一个Service,并且在onBinder方法中返回第2步中实现的那个Stub类的子类(实现类)。
2.客户端
2.1拷贝AIDL文件
将服务端的AIDL文件拷贝到客户端下相同的位置,相同的位置意味着包名AIDL文件名都要相同:com.example.aidl.server.RemoteWebpage.aidl。
2.2建立连接
继承ServiceConnection,重写onServiceConnected(ComponentName name, IBinder service),onServiceDisconnected(ComponentName name)函数建立与服务端的连接。
package com.example.aidl.client;
import com.example.aidl.server.RemoteWebpage;
import android.support.v7.app.ActionBarActivity;
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.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity implements OnClickListener{
private final static String TAG = "AIDLClient" ;
private Button btn_bind =null , btn_getinfo = null ;
private TextView tv = null ;
private RemoteWebpage remoteWebpage = null ;
private String actionName = "com.example.remote.webpage" ;
private String urlInfo = null ;
private Boolean isBind = false ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_bind = (Button) findViewById(R.id.btu_bind) ;
btn_getinfo = (Button) findViewById(R.id.btu_getinfo) ;
tv = (TextView) findViewById(R.id.text) ;
btn_bind.setOnClickListener(this) ;
btn_getinfo.setOnClickListener(this) ;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private class MyServiceConnect implements ServiceConnection
{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
Log.i(TAG, "connection.......") ;
remoteWebpage = RemoteWebpage.Stub.asInterface(service) ;
if(remoteWebpage == null )
{
tv.setText("connection failed!!") ;
return ;
}
else
{
isBind = true ;
btn_bind.setText("断开") ;
tv.setText("connected") ;
try {
urlInfo = remoteWebpage.getCurrentPageUrl() ;
System.out.println(urlInfo);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
btn_getinfo.setEnabled(true) ;
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
Log.i(TAG, "service is disconnected") ;
}
}
MyServiceConnect conn = new MyServiceConnect() ;
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btu_bind:
if(!isBind)
{
Intent intent = new Intent(actionName) ;
bindService(intent, conn, BIND_AUTO_CREATE) ;
}
else
{
Log.i(TAG, "disconnect") ;
unbindService(conn) ;
btn_getinfo.setEnabled(false) ;
btn_bind.setText("连接") ;
isBind = false ;
tv.setText("disconnected") ;
}
break;
case R.id.btu_getinfo :
tv.setText(urlInfo) ;
default:
break;
}
}
}
先运行服务端然后运行客户端,客户端就可以获取服务端的信息。