这个服务其实很简单,服务端,我们只要实现一个AIDL的接口文档,然后我们在服务的onBind返回AIDL的对象。
下面是AIDL接口的代码:
package com.test.testaidlservice; // Declare any non-default types here with import statements interface ITest { String getStr(); int getInt(); }
接口代码中实现了2个方法,一个是取字符串,另外一个是取整数,在我们进行APP开发的时候,我们可以实现我们需要的方法。
现在开始实现服务端的代码:
package com.test.testaidlservice; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import java.util.Timer; import java.util.TimerTask; /** * Created by Administrator on 2016/06/13 0013. */ public class testService extends Service { private int[] ins = {0,10,55,2,45,102}; private String[] strs = {"aa","fff","dd","ee","bb","cc"}; private int ints; private String str; private ITestEx mItestEx; private Timer timer; public class ITestEx extends ITest.Stub{ @Override public String getStr() throws RemoteException { return str; } @Override public int getInt() throws RemoteException { return ints; } } public void onCreate() { super.onCreate(); mItestEx = new ITestEx(); timer=new Timer(); timer.schedule(new TimerTask() { @Override public void run() { int rand = (int)(Math.random()*6); ints = ins[rand]; str = strs[rand]; Log.i("TAG",""+rand); } },2000,6000); } public IBinder onBind(Intent intent) { return mItestEx; } public void onDestroy() { timer.cancel(); } }
我们定义了2个数组里简单的操作,创建一个类,继承Stub,这里需要注意的就是只要我们创建了AIDL的接口,Stub这个java类是自动构建的,我们只需要继承它就可以了,然后我们在getStr跟getInt这2个方法中实现我们需要返回的数据就可以了。
这里我们使用了一个时钟,每6秒执行一次,在业务上我们可能需要写更多的代码来实现业务需求。
在onBind方法中,我们需要把mItestEx这个IBinder的对象返回出去。
接着我们来实现客户端:
package com.test.testwebview; 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.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; import android.view.Menu; import android.view.MenuItem; import android.widget.Button; import android.widget.EditText; import com.test.testaidlservice.ITest; public class MainActivity extends AppCompatActivity { private ITest stub; private Button start,get; private EditText str,ins; private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { stub = ITest.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { stub = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); init(); } private void init() { start = (Button)findViewById(R.id.start); get = (Button)findViewById(R.id.get); ins = (EditText)findViewById(R.id.ints); str = (EditText)findViewById(R.id.str); final Intent intent = new Intent(); intent.setAction("com.test.testaidlservice.action.aidl_service"); start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { bindService(intent, conn, Service.BIND_AUTO_CREATE); start.setEnabled(false); } }); get.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { str.setText(stub.getStr()); ins.setText(stub.getInt()+""); } catch (RemoteException e) { e.printStackTrace(); } } }); }
申明了一个ITest接口的对象,实现了ServiceConnection类,在ServiceConnection类中
onServiceConnected方法中,我们实例化了ITest的对象。 现在我们可以进行服务链接了,链接后我们通过按钮get的点击事件获取需要的数据。
Android进程之间通信异常;主要原因是客户端的aidl文件和与远程调用的Service的aidl文件包名不同处理方式一般就是在客户端要一个与远程暴露出来的接口包名要一致
否则会报:java.lang.SecurityException: Binder invocation to an incorrect interface进程通信异常
如图:
1 Comment
源码链接:http://pan.baidu.com/s/1c1Fylo 密码:nm9j