Android性能优化---AIDL的实现

首先,来了解一下AIDL是什么?主要是干了一些什么事情?

AIDL是一种接口定义语言,主要的使用场景是在进程间的通信,通过它,我们在两个进程中依靠这套接口定义,去相互访问对方的数据。

这个AIDL在编写完成以后,通过make project就能在build/generated/source/aidl/debug目录下,生成一个接口文件,通过这个文件,我们可以调用里面的方法,实现两个进程的通信

13083158-6d7021acbfcf938c.png

我们切换一下视图结构: Structure


13083158-faac39b7656bd644.png

通过上面的视图,我们发现aidl文件有两个部分。

其中
Proxy -- 代理 相当于客户端。CS架构中的Client
Stub -- 存根 相当于服务器。CS架构中的Server

这两个在通信中的作用,下图画的非常清楚

13083158-67e6003a4cd52d12.png

具体实现:

在main目录下新建aidl文件夹


13083158-e98757557a3016f2.png

新建aidl文件,bean目录下的Person.aidl和IMyAidl.aidl文件


13083158-a38963084402a423.png
13083158-52c92fc0b28f1f91.png

Person.aidl文件

// Person.aidl
package furobot.com.lsn6_aidl;

//声明一个实体类在一个包里
parcelable Person;

IMyAidl.aidl

// IMyAidl.aidl
package furobot.com.lsn6_aidl;

// Declare any non-default types here with import statements

interface IMyAidl {

//除了基本的数据类型,其他类型的参数都需要表上方向的类型,in 输入 ,out 输出 ,inout 输入输出
void addPerson(in Person person);//添加Person

List<Person> getPersonList();//获取Person列表
}

然后,进行make project

13083158-43e1d2c30dc043b4.png

最后,会在build目录下,生成一个aidl接口文件


13083158-71a567a1b7d9f1d3.png

到了,这一步,我们开始编写通信的相关代码了,我们实现一个添加人(对象)和展示人(对象)的一个功能。我们在另外一个进程服务里面去处理对象的添加和展示,然后将处理后的结果返回给当前进程。

创建一个服务,并在主配置清单里面声明它在aidl进程里面

  <service android:name=".MyAidlService"
            android:enabled="true"
            android:exported="true"
            android:process=":aidl"/>
package furobot.com.lsn6_aidl;

import android.app.Person;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

/**
 * 服务实现接口,在onBind()中返回这个Binder,客户端就能拿到可以操作的数据了
 */
public class MyAidlService extends Service{

    private static final String TAG = "MyAidlService";

    private ArrayList<furobot.com.lsn6_aidl.bean.Person> mPersons;

    public MyAidlService(){

    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        mPersons = new ArrayList<>();
        Log.e(TAG,"MyAidlService onBind");
        return mBinder;
    }

    private IBinder mBinder = new IMyAidl.Stub() {
        @Override
        public void addPerson(furobot.com.lsn6_aidl.bean.Person person) throws RemoteException {
            mPersons.add(person);
        }

        @Override
        public List<furobot.com.lsn6_aidl.bean.Person> getPersonList() throws RemoteException {
            return mPersons;
        }
    };
}

最后,在Activity里面进行调用

package furobot.com.lsn6_aidl;

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.TextView;

import java.util.List;
import java.util.Random;

import furobot.com.lsn6_aidl.bean.Person;

public class MainActivity extends AppCompatActivity {

    private IMyAidl myAidl;
    private TextView mTv;

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //连接成功后,拿到Binder,转换成AIDL,在不同的进程中返回代理
            myAidl = IMyAidl.Stub.asInterface(service); //将Ibinder转换成AIDL接口,这样才能调用里面的方法
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTv = findViewById(R.id.tv_text);
    }

    public void startService(View view){

        bindService(new Intent(this,MyAidlService.class),mConnection,BIND_AUTO_CREATE);
    }

    public void addPerson(View view){
        Random random = new Random();
        Person person = new Person("shixin" + random.nextInt(10));

        try {
            myAidl.addPerson(person);
            List<Person> personList = myAidl.getPersonList(); //调用远程的getPersonList()方法
            mTv.setText(personList.toString());
        } catch (RemoteException e) {
            e.printStackTrace();
        }

    }
}

效果图


13083158-6695a29881a35418.png

猜你喜欢

转载自blog.csdn.net/weixin_33972649/article/details/87048875