Android Studio实现AIDL跨进程通信

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ljttianqin/article/details/78184788

AIDL(Android Interface Definition Language):安卓接口定义语言的缩写,是一种android内部进程通信接口的描述语言,通过它可以定义进程间的通信接口。

本文参考:http://www.runoob.com/w3cnote/android-tutorial-service-3.html ,把服务端实现和客户端实现合在一起在同一项目下进行实现,因此,对概念的介绍理解可查看参考网页。

环境:
android studio 2.3.3
模拟器:BlueStacks

项目主要目录:



Step 1:创建Person.aidl和Salary.aidl的文件

Person.aidl

// Person.aidl
package com.example.aidltest;

parcelable Person;
Salary.aidl:

// Salary.aidl
package com.example.aidltest;

parcelable Salary;
Step 2:分别建立Person类与Salary类,实现Parcelable接口,重写对应的方法

Person.java:

package com.example.aidltest;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Created by Jinato on 2017/9/30.
 */

public class Person implements Parcelable{
    private Integer id;
    private String name;

    public Person(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    public Person() {
    }

    protected Person(Parcel in) {
        name = in.readString();
    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in.readInt(), in.readString());
        }

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(id);
        dest.writeString(name);
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Person person = (Person) o;

        if (id != null ? !id.equals(person.id) : person.id != null) return false;
        return name != null ? name.equals(person.name) : person.name == null;

    }

    @Override
    public int hashCode() {
        int result = id != null ? id.hashCode() : 0;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        return result;
    }
}
Salary.java:
package com.example.aidltest;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Created by Jinato on 2017/9/30.
 */

public class Salary implements Parcelable{
    private String type;
    private Integer salary;

    public Salary() {
    }

    public Salary(String type, Integer salary) {
        this.type = type;
        this.salary = salary;
    }

    protected Salary(Parcel in) {
        type = in.readString();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(type);
        dest.writeInt(salary);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final Creator<Salary> CREATOR = new Creator<Salary>() {
        @Override
        public Salary createFromParcel(Parcel in) {
            return new Salary(in.readString(), in.readInt());
        }

        @Override
        public Salary[] newArray(int size) {
            return new Salary[size];
        }
    };

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public Integer getSalary() {
        return salary;
    }

    public void setSalary(Integer salary) {
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "工作:'" + type + '\'' + ", 薪水:" + salary ;
    }
}
Step 3:创建一个ISalary.aidl的文件,在里面写一个简单的获取工资信息和查询Person的方法

// ISalary.aidl
package com.example.aidltest;

import com.example.aidltest.Salary;
import com.example.aidltest.Person;

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

interface ISalary {
    Salary getMsg(in Person owner);
    String queryPerson(int num);
}
Step 4:编写AidlService

package com.example.aidltest;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

import com.example.aidltest.Person;
import com.example.aidltest.Salary;
import com.example.aidltest.ISalary.Stub;


import java.util.HashMap;
import java.util.Map;

/**
 * Created by Jinato on 2017/9/30.
 */

public class AidlService extends Service {

    private static String[] names = {"AA", "BB", "CC", "DD"};
    private SalaryBinder salaryBinder;
    private static Map<Person,Salary> ss = new HashMap<Person, Salary>();
    //初始化Map集合,这里在静态代码块中进行初始化,当然你可也以在构造方法中完成初始化
    static
    {
        ss.put(new Person(1, names[0]), new Salary("码农", 2000));
        ss.put(new Person(2, names[1]), new Salary("歌手", 20000));
        ss.put(new Person(3, names[2]), new Salary("学生", 20));
        ss.put(new Person(4, names[3]), new Salary("老师", 2000));
    }

    @Override
    public void onCreate() {
        super.onCreate();
        salaryBinder = new SalaryBinder();
    }

    @Override
    public void onDestroy() {
        System.out.println("服务结束");
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return salaryBinder;
    }

    public class SalaryBinder extends Stub {

        @Override
        public Salary getMsg(Person owner) throws RemoteException {
            return ss.get(owner);
        }

        @Override
        public String queryPerson(int num) throws RemoteException {
            if (num > 0 && num < 5) {
                return names[num - 1];
            }
            return null;
        }
    }
}
注册Service:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.aidltest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".AidlService">
            <intent-filter>
                <action android:name="android.intent.action.AIDLService" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </service>
    </application>

</manifest>
Step 5:编写布局文件

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.aidltest.MainActivity">

    <TextView
        android:id="@+id/txt_name"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="31dp"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_query"
        tools:layout_constraintLeft_creator="1"
        tools:layout_constraintRight_creator="1" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="请输入要查询的序号:"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        tools:layout_constraintTop_creator="1"
        tools:layout_constraintRight_creator="1"
        android:layout_marginTop="20dp"
        tools:layout_constraintLeft_creator="1"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintHorizontal_bias="1.0" />

    <EditText
        android:id="@+id/edit_num"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:hint="请输入整数(1~4)"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView"
        tools:layout_constraintRight_creator="1"
        tools:layout_constraintLeft_creator="1" />

    <Button
        android:id="@+id/btn_query"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="查询"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        tools:layout_constraintRight_creator="1"
        tools:layout_constraintLeft_creator="1"
        app:layout_constraintHorizontal_bias="0.0"
        tools:layout_constraintTop_creator="1"
        android:layout_marginTop="33dp"
        app:layout_constraintTop_toBottomOf="@+id/edit_num" />

</android.support.constraint.ConstraintLayout>
Step 6:MainActvitiy的实现定义一个ServciceConnection对象,重写对应方法,再接着在bindService,然后再Button的点击事件中获取Salary对象并显示出来

package com.example.aidltest;

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.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = "AIDL";
    private EditText edit_num;
    private Button btn_query;
    private TextView text_show;
    private ISalary salaryService;
    private ServiceConnection conn = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            salaryService = ISalary.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            salaryService = null;
        }
    };

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

        //绑定远程Service
        Intent service = new Intent("android.intent.action.AIDLService");
        service.setPackage("com.example.aidltest");

        bindService(service, conn, BIND_AUTO_CREATE);
        btn_query.setOnClickListener(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        this.unbindService(conn);
    }

    private void bindViews() {
        edit_num = (EditText) findViewById(R.id.edit_num);
        btn_query = (Button) findViewById(R.id.btn_query);
        text_show = (TextView) findViewById(R.id.txt_name);
    }

    @Override
    public void onClick(View v) {
        try {
            int id = Integer.parseInt(edit_num.getText().toString());
            String name = salaryService.queryPerson(id);
            Salary salary = salaryService.getMsg(new Person(id, name));
            text_show.setText(name + "的" + salary.toString());
        } catch (RemoteException e) {
            e.printStackTrace();
        }
//        text_show.setText("");
    }

}
运行效果:


完整代码下载:Android Studio实现AIDL跨进程通信DEMO


展开阅读全文

没有更多推荐了,返回首页