一个Android远程服务例程。在例子中涉及的原理或其他知识,请自行搜索。
在Android系统中,每个应用程序都运行在自己的 进程中。 跨进程的服务称为远程服务。其原理类似Java 的Remote Method Invocation/RMI ,参考 远程方法调用RMI初步 。Android远程服务遵循服务器-客户端模型。因此服务器-客户端之间的协议,可以用Java接口封装。
在RMI中直接使用Java语言定义远程接口,而Android为了简化远程服务开发,如同CORBA 那样,使用Interface Definition Language ,为 Android IDL(AIDL).1.定义远程接口
AIDL类似Java语言,不用加访问权限修饰符public,private,protected等,也不能用final,static 。在一个Android项目中创建Java包interfaces并添加AIDL文件:package interfaces;
interface IHello {
String hello(String str) ;
}
如果aidl文件语法正确,开发环境自动生成真正的Java接口。
package interfaces;
public interface IHello extends android.os.IInterface {
public static abstract class Stub extends android.os.Binder implements IHello {/**88行*/}
public String hello(String str) throws android.os.RemoteException;
}
注意类层次IHello extendsandroid.os.IInterface
abstract class IHello. Stub extends android.os.Binder implements IHello
2.服务器编程
编写Stub的实现类
package com.ServiceRemote;
import interfaces.IHello;
public class StubImpl extends IHello.Stub {
public String hello(String str) throws android.os.RemoteException {
return "echo:" + str ;
}
}
编写远程服务类
package com.ServiceRemote;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import interfaces.IHello;
public class ServiceRemote extends Service {
private final IHello.Stub stub = new StubImpl();
@Override public IBinder onBind(Intent intent) {
return stub;
}
}
注册服务:AndroidManifest中添加<service >
<application android:icon="@drawable/icon" android:label="@string/app_name">
<service android:name=".ServiceRemote">
<intent-filter>
<action android:name="com.ServiceLocal.SERVICE_REMOTE"/>
</intent-filter>
</service>
</application>
打包后安装到天天模拟器或手机中。
3.客户端编程
为了体现跨进程,客户端另外建立一个项目AndroidApp,注意将前面的interfaces包复制到这个项目中来。NetBeans中,文件视图中复制粘贴。
package com.yqj2065;
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.view.View;
import android.widget.Button;
import android.widget.Toast;
import interfaces.IHello;
public class UI extends Activity {
private String actionName= "com.ServiceLocal.SERVICE_REMOTE";
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btnConn = (Button) findViewById(R.id.btnConn);
btnConn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent inttService = new Intent();
inttService.setAction(actionName);
bindService(inttService, connService, Service.BIND_AUTO_CREATE);
}
});
}
private ServiceConnection connService = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IHello rHello = IHello.Stub.asInterface(service);
if (rHello != null) {
try {
//方法调用
String strMsg = rHello.hello("你好!");
Toast.makeText(UI.this, strMsg, Toast.LENGTH_LONG).show();
} catch (RemoteException e) { }
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
};
}
注意:actionName要是服务器端注册使用的字符串。
打包后安装到天天模拟器或手机中,运行。