在写这篇博客之前了,先给大家说一下,在2017年,人民币将会出现贬值,说不定会产生新一轮的经济危机,希望大家不要只注重于代码!
介绍AIDL之前,我先给大家普及一下,进程间的通信有: Intent的隐式跳转传值,广播,内容提供者,还有一种就是咋们今天所说的AIDL。
AIDL是一个缩写,全称是 Android Interface Definition Language,也就是Android接口定义语言。它的目的了主要是为了实现进程间的通信。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。
AIDL其实通过我们写的aidl文件,帮助我们生成了一个接口,一个Stub类用于服务端,一个Proxy类用于客户端调用.
这是一个在AS下最简单的一个AIDL编程:
1.服务端创建一个aidl目录,然后在该目录下新建一个.aidl为后缀的接口类,该类定义远程调用的接口方法。
2.build编译之后会在app/build/generated/source/aidl/debug目录下会生成aidl远程实现类,该类是AS自动生成的。
3.在AndroidManifest.xml下配置Service的action和process属性。
4.将服务端的aidl目录拷贝到客户端相应的目录下,然后编写客户端调用代码,AS下简单的aidl编程就ok了。
5.利用Aidl实现跨进程传递数据。
什么也不说了,直接上代码吧,
我们写一个,在客户端输入进行搜索,服务端给提供搜索内容。实现思路了就是:服务端需要提供一个带有值的binder对象,这个binder对象和客户端共同实现同一个接口,客户端通过这个binder对象拿到接口对象去调用接口里面的方法获取相应的值。
我们先写服务端:
首先我们在服务端建一个aidl
interface IMyAidlInterface { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ String queryNameById(int id); }并且builder一下
创建一个serverse
public class Myserver extends Service { private String[] names = new String[]{"张学友","刘德华","黎明","郭富城"}; private MyBinder ibinder = new MyBinder(); @Override public IBinder onBind(Intent intent) { return ibinder; } //增强版的IBinder //这个记住在清单文件里配置一下IMyAidlInterface.Stub是咋们写的接口,看一下builder后在sourse文件下aidl下debug下找到IMyAidlInterface文件就可以看到stub();
private class MyBinder extends IMyAidlInterface.Stub { @Override public String queryNameById(int id) throws RemoteException { //id只能是1 到4 if(id <= 0 || id > names.length){ return "苍姐姐"; }else{ return names[id-1]; } } }}
<service android:name=".Myserver" > <intent-filter> //一定要写action <action android:name="lianxi.bawei.com.aidllianxi.Myserver"/> </intent-filter> </service>
然后再写客户端
首先先粘贴服务端的aidl文件,然后是布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="学号" /> <EditText android:id="@+id/et_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="number"/> <Button android:id="@+id/bt_query" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="query" android:text="查询" /> <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="" /> </LinearLayout>
然后是客户端的Mainactivity:
package lianxi.bawei.com.aidlbind; 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.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import lianxi.bawei.com.aidllianxi.IMyAidlInterface; public class MainActivity extends AppCompatActivity { private EditText et_id; private TextView tv_name; private MyServiceConnection conn; private IMyAidlInterface iListener; private Button bt_query; private class MyServiceConnection implements ServiceConnection { //绑定的服务是一个 远程的服务 aidl语言 传递过来的对象 :代理对象 代理对象不能直接使用 //需要使用Stub里面的一个方法 asInterface()把代理对象转化成真实对象 再使用 @Override public void onServiceConnected(ComponentName name, IBinder service) { //把代理对象转化成真实对象 Toast.makeText(MainActivity.this, "连接成功", Toast.LENGTH_SHORT).show(); Log.i("xxx",service.toString()); iListener=IMyAidlInterface .Stub.asInterface(service); //IMyAidlInterface.Stub } @Override public void onServiceDisconnected(ComponentName name) { Toast.makeText(MainActivity.this, "连接失败", Toast.LENGTH_SHORT).show(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_id = (EditText) findViewById(R.id.et_id); tv_name = (TextView) findViewById(R.id.tv_name); bt_query = (Button) findViewById(R.id.bt_query); //绑定服务 //Android5.0中service的intent一定要显性声明,当这样绑定的时候不会报错。 Intent service = new Intent("lianxi.bawei.com.aidllianxi.Myserver"); conn = new MyServiceConnection(); bindService(service, conn, BIND_AUTO_CREATE); bt_query.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String idStr = et_id.getText().toString().trim(); if (TextUtils.isEmpty(idStr)) { Toast.makeText(MainActivity.this, "姐姐 学号不能为空", Toast.LENGTH_SHORT).show(); } else { int id = Integer.parseInt(idStr); //调用接口对象的方法(就是调用真实对象的方法) try { String name = iListener.queryNameById(id); tv_name.setText(name); } catch (RemoteException e) { e.printStackTrace(); //Toast.makeText(this, "服务器端出现了错误", 0).show(); Toast.makeText(MainActivity.this, "服务端出现错误", Toast.LENGTH_SHORT).show(); } } } }); } @Override protected void onDestroy() { super.onDestroy(); unbindService(conn); } }以上是我对aidl的简单了解。