一个Android远程服务例程。在例子中涉及的原理或其他知识,请自行搜索。
在Android系统中,每个应用程序都运行在自己的 进程中。 跨进程的服务称为远程服务。其原理类似Java 的Remote Method Invocation/RMI ,参考 远程方法调用RMI初步 。Android远程服务遵循服务器-客户端模型。因此服务器-客户端之间的协议,可以用Java接口封装。
在RMI中直接使用Java语言定义远程接口,而Android为了简化远程服务开发,如同CORBA 那样,使用Interface Definition Language ,为 Android IDL(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
编写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>
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要是服务器端注册使用的字符串。
打包后安装到天天模拟器或手机中,运行。