android AIDL基础

Android的每一个应用都是运行在单独的一个进程里。进程间的通信主要有以下四种:

1> Activity:可以结合Intent使用,启动其他进程的活动;

2> 广播:广播为跨进程间的通信;

3> ContentProvide:内容提供者,以Cursor对象访问其他进程数据或者为其他进程提供数据;

3> Service:主要通过AIDl实现进程间通信;

AIDL全程为安卓接口定义语言。

具体参考: http://blog.csdn.net/luoyanglizi/article/details/51980630

下面通过在Androidstudio上实现Client向服务端提交数据的实例对AIDL进行学习。

Client:

1> 我们都知道,每一个进程都有自己的独立内存。如果需要在进程间传递对象,则需将对象序列化。

#java语言

创建类,直接实现Serializable接口

#Android独有,实现Parcelable接口

创建Persion类,实现Parcelable接口

package com.example.aidltest;

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

/**
 * Created by 阿正 on 2017/4/10 0010.
 */

public class Persion implements Parcelable {
    public String name;
    public int age;

    public Persion() {
    }

    protected Persion(Parcel in) {
        name = in.readString();
        age = in.readInt();
    }

    public Persion(String name, int age) {
        this.name = name;
        this.age = age;
    }

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

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

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

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Persion{" +
                "name=‘" + name + ‘\‘‘ +
                ", age=" + age +
                ‘}‘;
    }
}

2> 创建AIDL

对应文件位置:

Persion.aidl

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

// Declare any non-default types here with import statements
parcelable Persion;

PersionManager.aidl

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

// Declare any non-default types here with import statements
// 这里引入的是Persion.aidl
import com.example.aidltest.Persion;

interface IPersionManager {
    // 定义方法,所有的返回值前不需要修饰关键字;如果非默认类型,需要在参数前添加 in/out/inout
    // in 客户端向服务端提供数据;out 客户端向服务端获取数据
    List<Persion> getPersion();
    void addPersion(in Persion ipersion);
}

到这里,创建结构类并序列化,创建AIDL已经完成。需要注意的是在创建Persion.aidl的时候,名字尽量和Persion.java一致。比如我之前创建IPersion.aidl时,clean项目的时候就报错。

客户端:客户端主要实现启动/停止service

package com.example.aidltest;

import android.content.ComponentName;
import android.content.Context;
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 android.widget.EditText;

import java.util.List;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private Button mAdd;
    private Button mConnect;
    private EditText mTextName;
    private EditText mTextAge;

    //是否连接服务端
    private boolean isconnect = false;

    private IPersionManager mPersionManager;
    private List<Persion> mPersions;
    public MainActivity() {
    }

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

        mTextName = (EditText) findViewById(R.id.text_name) ;
        mTextAge = (EditText) findViewById(R.id.text_age);
        mAdd = (Button) findViewById(R.id.add);
        mConnect = (Button)findViewById(R.id.connect);
        mAdd.setOnClickListener(this);
        mConnect.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.add:
                // 调用服务端实现的方法,对数据进行改动
                addBook();
                break;
            case R.id.connect:
                // 启动service并绑定
                Intent intent = new Intent();
                intent.setAction("azheng");
                intent.setPackage("com.example.aidltestservice");
                bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE);
                break;
        }
    }

    private void addBook(){
        if (!isconnect){
            Log.d("azheng" ,"clent: Not connected,please connect to service first!");
            return;
        }
        if (mPersionManager == null){return;}
        Persion persion = new Persion();
        String name = mTextName.getText().toString();
        persion.setName(name);
        int age = Integer.parseInt(mTextAge.getText().toString());
        persion.setAge(age);
        try {
            mPersionManager.addPersion(persion);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    // 创建ServiceConnection,与服务端连接
    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d("azheng" ,"clent: connected");
            // 获得服务端的IPersionManager
            mPersionManager = IPersionManager.Stub.asInterface(service);
            isconnect = true;
            try {
                Log.d("azheng" ,"clent: before add:" + mPersionManager.getPersion().toString());
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d("azheng" ,"clent: connected");
            isconnect = false;
        }
    };

    @Override
    protected void onStop() {
        super.onStop();
        if (isconnect){
            unbindService(serviceConnection);
        }
    }
}

服务端:

服务端的Persion.java Persion.aidl IPersionManager.aidl三个文件的包名,内容需要与client一致。因此最好的办法是直接从client复制过来。

Persion.java

// 这里的包名需要与服务端一致
package com.example.aidltest;

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

/**
 * Created by 阿正 on 2017/4/10 0010.
 */

public class Persion implements Parcelable {
    public String name;
    public int age;

    public Persion() {
    }

    protected Persion(Parcel in) {
        name = in.readString();
        age = in.readInt();
    }

    public Persion(String name, int age) {
        this.name = name;
        this.age = age;
    }

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

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

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

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Persion{" +
                "name=‘" + name + ‘\‘‘ +
                ", age=" + age +
                ‘}‘;
    }
}

具体的服务类AIDLService

package com.example.aidltestservice;

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 com.example.aidltest.IPersionManager;
import com.example.aidltest.Persion;

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

/**
 * Created by 阿正 on 2017/4/10 0010.
 */

public class AIDLService extends Service {
    private List<Persion> mPersions = new ArrayList<>();

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

    // 实现IPersionManager。aidl
    private final IPersionManager.Stub persionManager = new IPersionManager.Stub(){

        @Override
        public List<Persion> getPersion() throws RemoteException {
            synchronized (this){
                if (mPersions != null){
                    return mPersions;
                }
            }
            return null;
        }

        @Override
        public void addPersion(Persion ipersion) throws RemoteException {
            synchronized (this){
                if (ipersion == null){
                    Log.d("azheng","service: persion from clent is null!");
                }else {
                    mPersions.add(ipersion);
                }
                Log.d("azheng","service: result" + mPersions.toString());
            }
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("azheng" ,"service: onCreate()");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("azheng" ,"service: onStartCommand()");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("azheng" ,"service: onDestroy()");
    }
}

ok,到这里就完成了。

补充一点:上面提到客户端和服务端的{Persion.java Persion.aidl IPersionManager.aidl}需要一致,为了方便复制,这里提供另一种方法。

1> 将Persion.java 文件拷贝到aidl文件夹中

2> 上面的操作会导致Persion.java文件编译器找不到,因为AndroidStudio是通过sourceSets来配置不同文件的访问路径的。

修改 build.gradle 文件:在 android{} 中间加上下面的内容:

sourceSets {
        main {
            java.srcDirs = java.srcDirs = [‘src/main/java‘, ‘src/main/aidl‘]
        }
    }
时间: 2024-10-18 22:20:58

android AIDL基础的相关文章

【Android 面试基础知识点整理】

针对Android面试中常见的一些知识点整理,Max 只是个搬运工,感谢本文中引用文章的各位作者,给大家分享了这么多优秀文章,对于其中的解析,是原作者个人见解,有错误和不准确的地方,也请大家积极指正. 本文将持续更新,同时我也将其放在Github上:Point-of-Android 同时可以看Max的个人博客:海上钢琴师 Android中的异步任务机制 Android中AsyncTak的使用与源码分析 http://blog.csdn.net/bboyfeiyu/article/details/

Android核心基础(手机卫士的一个知识点总结)

注意:有些功能是需要权限的,在这里并没有写出来,在程序运行中,根据程序报的错误,添加相应的权限即可,里面的具体里面可能有一些小细节,没有明确的写出来,具体的需要在程序中自己调试,解决. 这个总结涵盖了Android的一些核心的内容,如四大组建Service.ContentProvider.BroadCastReceiver.Activity,而且四大组建都必须在清单文件中注册. 还涉及了Android手机底层的一些功能,如读取联系人.短信等.还有一些看似牛别点技术,什么短息拦截,电话拦截,黑名单

Android零基础入门第64节:揭开RecyclerView庐山真面目

大家还记得之前在第38期~第50期都在学习列表控件吗,其中用了8期讲ListView的使用,相信都已经掌握好了吧.那么本期一起来学习Android 5.X新增的一个列表组件,那就是RecyclerView的使用. 一.RecyclerView概述 从前面的学习我们知道,ListView的功能非常强大,几乎绝大部分应用程序都会使用到,虽然也学会一些方法技巧来提升ListView的效率,但其性能还是不是很完美. 另外ListView的可扩展性相对来说比较弱,以前要实现每个列表项的高度不同的界面,或者

Android零基础入门第61节:滚动视图ScrollView

原文:Android零基础入门第61节:滚动视图ScrollView 前面几期学习了ProgressBar系列组件.ViewAnimator系列组件.Picker系列组件和时间日期系列组件,接下来几期继续来学习常见的其他组件. 一.ScrollView概述 从前面的学习有的同学可能已经发现,当拥有很多内容时屏幕显示不完,显示不全的部分完全看不见.但是在实际项目里面,很多内容都不止一个屏幕宽度或高度,那怎么办呢?那就需要本节学习的ScrollView来完成. 在默认情况下,ScrollView只是

Android零基础入门第60节:日历视图CalendarView和定时器Chronometer

原文:Android零基础入门第60节:日历视图CalendarView和定时器Chronometer 上一期学习了AnalogClock.DigitalClock和TextClock时钟组件,本期继续来学习日历视图CalendarView和定时器Chronometer. 一.CalendarView 日历视图(CalendarView)可用于显示和选择日期,用户既可选择一个日期,也可通过触 摸来滚动日历.如果希望监控该组件的日期改变,则可调用CalendarView的 setOnDateCha

Android零基础入门第62节:搜索框组件SearchView

原文:Android零基础入门第62节:搜索框组件SearchView 一.SearchView概述 SearchView是搜索框组件,它可以让用户在文本框内输入文字,并允许通过监听器监控用户输入,当用户输入完成后提交搜索时,也可通过监听器执行实际的搜索. SearchView默认是展示一个search的icon,点击icon展开搜索框,也可以自己设定图标.用SearchView时可指定如下表所示的常见XML属性及相关方法. 如果为SearchView增加一个配套的ListView,则可以为Se

Android Activity基础详解

一.Activity简介 Activity 是一个应用组件,用户可与其提供的屏幕进行交互,以执行拨打电话.拍摄照片.发送电子邮件或查看地图等操作. 每个 Activity 都会获得一个用于绘制其用户界面的窗口.窗口通常会充满屏幕,但也可小于屏幕并浮动在其他窗口之上. 一个应用通常由多个彼此松散联系的 Activity 组成. 一般会指定应用中的某个 Activity 为"主" Activity,即首次启动应用时呈现给用户的那个 Activity. 而且每个 Activity 均可启动另

Android核心基础第五天

一.学习目标及要求 课程目标 课程内容(必须讲的内容,就是讲课的知识点的顺序) * 掌握Activity 配置 * 掌握 Intent 显示意图 * 掌握 Intent 隐式意图 * 掌握两种意图的使用场景 * 掌握 activity 开启的数据传递 * 掌握activity的生命周期 * 掌握横竖屏切换的生命周期 * 掌握不同android版本 生命周期的细微差别 * 掌握开启activity获取返回值 * 掌握请求码 结果码的作用 * 掌握程序入口activity配置参数 * 掌握显示意图 

20145239 杜文超 实验四 Android开发基础

20145239实验四 Android开发基础 实验内容 基于Android Studio开发简单的Android应用并部署测试 了解Android组件.布局管理器的使用 掌握Android中事件处理机制 Android Studio安装 实验步骤 安装 JDK 并配置 JDK 环境变量 依次使用计算机->系统属性->高级系统设置->高级->环境变量,然后新建一个JAVA_HOME变量,令它为计算机中安装JDK的位置: 安装Andriod Studio并配置 1.双击运行Andri