android studio 创建aidl

前言
看了很多CSDN大牛的博客,心血澎湃决定以后要把自己学的东西用博客记录下来。之前也陆陆续续写了一些 但是都随便潦草应付,后来发现排名靠前的博客都是那么认真负责,我以后也不能随便吧,我最看不起坑队友,误人子弟的事了。呵呵 也要锻炼自己的意志吧,相信自己日积月累,水滴石穿!废话不多说了进入正题。
很多程序员从Eclipse开发编写AIDL的流程已经是了如指掌了,但是在Android Studio上我百度了一下很多人没有把创建AIDL 进行跨进程通讯的例子步骤写的很详细,在这里我主要讲解一下Android Studio创建AIDL的流程,帮助AS新手快速创建AIDL。

1、先建立一个android工程,用作服务端
AS 右键》NEW 》 Module 创建了一个 aidl 的Module

2、创建一个实例Student.java

在com.example.zdq 这个包下 NEW》Package 创建了一个aidl的空包
新建一个Student 实例 implement Parcelable这个接口才能进行IPC通讯

package com.example.zdq.aidl;

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

/**
 * Created by Administrator on 2017/8/24.
 */

public class Student implements Parcelable {

    public int sno;
    public String name;
    public int sex;
    public int age;

    public  Student(){

    }
    protected Student(Parcel in) {
    }

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

    public void readFromParcel(Parcel in){
        sno=in.readInt();
        name=in.readString();
        sex=in.readInt();
        age=in.readInt();
    }

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

    public static final Creator<Student> CREATOR = new Creator<Student>() {
        @Override
        public Student createFromParcel(Parcel in) {
            return new Student(in);
        }

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

需要注意的是,readFromParcel和writeToParcel操作数据成员的顺序要一致

3、创建IStudentService.aidl
鼠标点击放在 aidl这个包下 AS自带新建AIDL文件功能 按照如图所示 创建一个IStudentService的AIDL文件 然后系统自动会生成 跟java同级目录aidl 同包名com.example.zdq.aidl 大家可以看图 IStudentService.aidl就在这个目录下面 IStudentService.aidl 里面的代码先别管 都是系统生成的
注意这里我先创建IStudentService.aidl 而不是创建Student.aidl 是因为AS有个BUG 不能创建跟实例同名的aidl

4、创建Student.aidl
ok接下来我们再创建一个跟Student实例一模一样的Student.aidl 鼠标放在com.example.zdq.aidl这个包上 右键 NEW》AIDL 命名为Student.aidl

// ad.aidl
package com.example.zdq.aidl;

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

parcelable Student;

注意的就是 parcelable 这个是小写 是一个类型 不是 Parcelable 接口

5、编写IStudentService.aidl 提供给客户端使用的方法

// IStudentService.aidl
package com.example.zdq.aidl;
import com.example.zdq.aidl.Student;
// Declare any non-default types here with import statements

interface IStudentService {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    List<Student> getStudents();
    void addStudent(in Student student);
}

到了这个一步 Build》Rebuild Project 如图所示就证明aidl创建ok了
这里写图片描述

6、创建服务端StudentService并且在AndroidMenifest中声明StudentService

StudentService代码

package com.example.zdq;

import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import com.example.zdq.aidl.IStudentService;
import com.example.zdq.aidl.Student;

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

/**
 * Created by Administrator on 2017/8/24.
 */

public class StudentService extends Service {


    private final static String TAG = "StudentService";
    private static final String PACKAGE_SAYHI = "com.example.test";

    private NotificationManager mNotificationManager;
    private boolean mCanRun = true;
    private List<Student> mStudents = new ArrayList<Student>();

    //这里实现了aidl中的抽象函数
    private final IStudentService.Stub mBinder=new IStudentService.Stub(){

        @Override
        public List<Student> getStudents() throws RemoteException {
            return mStudents;
        }

        @Override
        public void addStudent(Student stu) throws RemoteException {

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

    @Override
    public void onCreate() {
        super.onCreate();
        ServiceWorker sw=new ServiceWorker();
        new Thread(sw).start();

        synchronized (mStudents) {
            for (int i = 1; i < 6; i++) {
                Student student = new Student();
                student.name = "student#" + i;
                student.age = i * 5;
                mStudents.add(student);
            }
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    class ServiceWorker implements Runnable
    {
        long counter = 0;

        @Override
        public void run()
        {
            // do background processing here.....
            while (mCanRun)
            {
                Log.d("scott", "" + counter);
                counter++;
                try
                {
                    Thread.sleep(2000);
                } catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
}

AndroidManifest.xml 代码

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

    package="com.example.zdq">

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

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service
            android:name="com.example.zdq.StudentService"
            android:process=":remote"
            android:exported="true"
            >
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />
                <action android:name="com.exmaple.aidl.StudentService" />
            </intent-filter>
        </service>
    </application>

</manifest>

7、整个项目包结构截图让大家看的更清楚

这里写图片描述

在这里我故意把build.gradle 文件也截图出来 就是看applicationId “com.example.aidl” 这个属性 这里跟我创建的包名是不一样的 有真机的朋友可以跑起来 用ps命令看一下 进程名就是com.example.aidl
这跟在客户端开启远程服务也有关系
Intent intent=new Intent(“com.exmaple.aidl.StudentService”); intent.setPackage(“com.example.aidl”);
bindService(intent,conn, Service.BIND_AUTO_CREATE);
如果 intent.setPackage(“com.example.zdq”);这样是调用不起来的

服务端ok了 下面编写客户端

8、然后创建android工程 命名aidlClient

9、创建一个跟服务端aidl文件所在一模一样的包名com.example.zdq.aidl

把Student.java文件copy过来
然后鼠标点击所在的包名 NEW》AIDL 随便取个名字 系统就会生成跟java同级目录aidl 同包名com.example.zdq.aidl 的一个aidl文件 删除该aidl文件 把服务端的IStudentService.aidl 和Student.aidl copy过来

当然记得跟服务端一样 Build》RebuildProject

10、然后在MainActivity中连接远程service 获取IBinder实例 调用IStudentService中的方法

package com.example.aidlclient;

import android.app.AlertDialog;
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.util.Log;
import android.view.View;
import android.widget.Button;

import com.example.zdq.aidl.IStudentService;
import com.example.zdq.aidl.Student;

public class MainActivity extends AppCompatActivity {

    private final static String TAG="client";
    private IStudentService mStudentBinder;
    ServiceConnection conn=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Log.i(TAG,"onServiceConnected>");
            mStudentBinder= IStudentService.Stub.asInterface(iBinder) ;
            try {
                Student stu= mStudentBinder.getStudents().get(0);
                showDialog(stu.toString());
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.i(TAG,"onServiceDisconnected");
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button start_btn= (Button) findViewById(R.id.start_btn);
        start_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.i(TAG,"onclick");
                Intent intent=new Intent("com.exmaple.aidl.StudentService");
                intent.setPackage("com.example.aidl");
                bindService(intent,conn, Service.BIND_AUTO_CREATE);
                if(mStudentBinder!=null){
                    Log.i(TAG,"mStudentBinder="+mStudentBinder);
                    try {
                        Student stu= mStudentBinder.getStudents().get(0);
                        showDialog(stu.toString());
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    public void showDialog(String message)
    {
        new AlertDialog.Builder(MainActivity.this)
                .setTitle("scott")
                .setMessage(message)
                .setPositiveButton("确定", null)
                .show();
    }

}

11、客户端aidlClient项目结构截图
这里写图片描述

用真机 先跑服务端 再跑客户端 看看效果吧。第一次这么认真写博客,有些写的不好地方请多多指教,可以一起交流交流!以后我也会坚持分享干货的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值