先说说Aidl传递参数类型
1.基本数据类型(除short类型)
2.String、charSequence
3.List,map
4.parcelable
第1步:定义一个*.aidl文件,eclipse会自动生成,android Studio需要编译一下(用Make project)
简单例子:
// IMyService.aidl package com.example.administrator.yunstore; // Declare any non-default types here with import statements interface IMyService { void setValue(String name); String getValue(); }
(以上是Android studio生成的java文件位置)
第2步:实现AIDL文件生成的JAVA接口Stub
package com.example.administrator.yunstore; import android.os.RemoteException; /** * Created by Administrator on 2016/7/11. */ public class Person extends IMyService.Stub { private String name; @Override public void setValue(String name) throws RemoteException { this.name=name; } @Override public String getValue() throws RemoteException { return name; } }
第3步:定义一个自己的service,在实现自己的service时,为了其他应用可以通过bindService来和我们的service进行交互,我们都要实现service中的onBind()方法,并且返回一个继承了Binder的内部类
import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; /** * Created by Administrator on 2016/7/11. */ public class useService extends Service { private IMyService.Stub iPerson=new Person(); @Override public IBinder onBind(Intent intent) { Log.i("service", "onBind..."); return iPerson; } }
第4步,同一个应用中的Activity为该Service中赋值,使用service
import android.app.Service; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.os.RemoteException; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private IMyService iMyService; private Button unBindButton,BindButton; private ServiceConnection conn=new ServiceConnection() { @Override//连接上服务 public void onServiceConnected(ComponentName componentName, IBinder iBinder) { iMyService=IMyService.Stub.asInterface(iBinder); if(iMyService!=null){ try { iMyService.setValue("设置值"); Toast.makeText(getApplicationContext(),"设定值成功",Toast.LENGTH_SHORT).show(); } catch (RemoteException e) { e.printStackTrace(); Toast.makeText(getApplicationContext(),"设定值失败"+e,Toast.LENGTH_SHORT).show(); } } } @Override//断开服务 public void onServiceDisconnected(ComponentName componentName) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { unBindButton= (Button) findViewById(R.id.unBind); BindButton= (Button) findViewById(R.id.Bind); unBindButton.setOnClickListener(new MyButtonListener()); BindButton.setOnClickListener(new MyButtonListener()); } private class MyButtonListener implements View.OnClickListener{ @Override public void onClick(View view) { switch (view.getId()){ case R.id.Bind:{ //绑定服务 bindService(new Intent("testAIDL"),conn, Service.BIND_AUTO_CREATE); break; } case R.id.unBind:{ //解绑服务 unbindService(conn); break; } } } } }
客户端:
第1步:客户端要想使用该服务,肯定要先知道我们的服务在aidl文件中到底对外提供了什么服务,对吧?所以,第一步,我们要做的就是,将aidl文件拷贝一份到客户端的程序中(这里一定要注意,包路径要和服务端的保持一致哦,例如服务端为cn.com.chenzheng_java.remote.a.aidl,那么在客户端这边也应该是这个路径)。
第2步:我们都知道,想要和service交互,我们要通过bindService方法,该方法中有一个ServiceConnection类型的参数。而我们的主要代码便是在该接口的实现中。
第3步:在ServiceConnection实现类的onServiceConnected(ComponentName name, IBinder service)方法中通过类似remoteServiceInterface = RemoteServiceInterface.Stub.asInterface(service);方式就可以获得远程服务端提供的服务的实例,然后我们就可以通过remoteServiceInterface 对象调用接口中提供的方法进行交互了。(这里的关键是通过*.Stub.asInterface(service);方法获取一个aidl接口的实例哦)
我们前面在服务端中说过了,必须提供一个intent-filter来匹配请求是否合法,所以我们在客户端访问服务的时候,还必须传递包含了匹配action的Intent哦。
客户端中使用服务端中的service范例:
private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName arg0) { } //因为有可能有多个应用同时进行RPC操作,所以同步该方法 @Override public synchronized void onServiceConnected(ComponentName arg0, IBinder binder) { //获得IPerson接口 person = IPerson.Stub.asInterface(binder); if(person != null){ try { //RPC方法调用 String name = person.getValue(); Toast.makeText(DemoAIDLActivity.this, "远程进程调用成功!值为 : "+name, Toast.LENGTH_LONG).show(); } catch (RemoteException e) { e.printStackTrace(); Toast.makeText(DemoAIDLActivity.this, "远程进程调用失败! ", Toast.LENGTH_LONG).show(); } } } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btn = (Button)findViewById(R.id.btn); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //该应用中不需要在manifest中配置RemoteService bindService(new Intent("forServiceAidl"), conn, Service.BIND_AUTO_CREATE); } }); }