iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android使用AIDL共享Room数据库
  • 527
分享到

Android使用AIDL共享Room数据库

aidlAndroid 2022-06-06 13:06:37 527人浏览 泡泡鱼
摘要

什么是aiDL: AIDL(Android Interface Definition Language),翻译成中文就是安卓接口定义语言的意思,

什么是aiDL:

AIDL(Android Interface Definition Language),翻译成中文就是安卓接口定义语言的意思,是用于定义服务端和客户端通信接口的一种描述语言。其主要作用是IPC(Android进程间通讯),简单的来说就是AIDL可以让一个APP使用另外一个APP的Service,使得两个或者多个APP之间可以信息交互,使得多个APP之间只需要使用一套代码,这样对于同一个功能就不用在多个APP中都写一遍逻辑了,减少了重复代码。

语法

AIDL的语法十分简单,与Java语言基本保持一致,需要记住的规则有以下几点:

AIDL文件以 .aidl 为后缀名
AIDL支持的数据类型分为如下几种:
八种基本数据类型:byte、char、short、int、long、float、double、boolean
String,CharSequence
实现了Parcelable接口的数据类型
List 类型。List承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象
Map类型。Map承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象
AIDL文件可以分为两类。一类用来声明实现了Parcelable接口的数据类型,以供其他AIDL文件使用那些非默认支持的数据类型。还有一类是用来定义接口方法,声明要暴露哪些接口给客户端调用,定向Tag就是用来标注这些方法的参数值
定向Tag。定向Tag表示在跨进程通信中数据的流向,用于标注方法的参数值,分为 in、out、inout 三种。其中 in 表示数据只能由客户端流向服务端, out 表示数据只能由服务端流向客户端,而 inout 则表示数据可在服务端与客户端之间双向流通。此外,如果AIDL方法接口的参数值类型是:基本数据类型、String、CharSequence或者其他AIDL文件定义的方法接口,那么这些参数值的定向 Tag 默认是且只能是 in,所以除了这些类型外,其他参数值都需要明确标注使用哪种定向Tag。定向Tag具体的使用差别后边会有介绍
明确导包。在AIDL文件中需要明确标明引用到的数据类型所在的包名,即使两个文件处在同个包名下

举例使用:

下面我举例使用AIDL实现一个APP访问另外一个APP创建的数据库

首先我们创建一个新的项目作为服务端APP,创建一个database,这里我使用Room框架。自定义类型User,直接上代码
build.gradle中引入room支持

    androidTestImplementation "android.arch.persistence.room:testing:1.1.1"
    implementation 'android.arch.persistence.room:runtime:1.1.1'
    annotationProcessor 'android.arch.persistence.room:compiler:1.1.1'
    androidTestImplementation "android.arch.persistence.room:testing:1.1.1"

实体类User,注意要在AIDL中使用自定义类型,实体类必须实现Parcelable接口来进行序列化。而且这个类必须添加一个无参的构造方法,通常无参的构造方法即使不写编译器也会帮我们自动生成,但是这里必须手动加上。

package com.example.testapp.database;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "user")
public class User implements Parcelable {
    public User() {
		//无参构造
    }
    protected User(Parcel in) {
        id = in.readLong();
        name = in.readString();
        sex = in.readString();
        age = in.readInt();
    }
    public static final Creator CREATOR = new Creator() {
        @Override
        public User createFromParcel(Parcel in) {
            return new User(in);
        }
        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @PrimaryKey
    @ColumnInfo(name = "id")
    private long id;
    @ColumnInfo(name = "name")
    private String name;
    @ColumnInfo(name = "sex")
    private String sex;
    @ColumnInfo(name = "age")
    private int age;
    @Override
    public int describeContents() {
        return 0;
    }
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(id);
        dest.writeString(name);
        dest.writeString(sex);
        dest.writeInt(age);
    }
}

创建UserDao:

package com.example.testapp.database;
import java.util.List;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
@Dao
public interface UserDao {
    @Query("SELECT * FROM user")
    LiveData<List> getUserLiveData();
    @Query("SELECT * FROM user")
    List getAll();
    @Insert
    void insert(User user);
    @Delete
    void delect(User user);
    @Update
    void update(User user);
}

Room数据库支持直接返回LiveData对象的查询结果,AIDL这个例子没有用到,有兴趣可以看我这篇博客
LiveData结合Room数据库使用以及线程问题

UserDatabase:

package com.example.testapp.database;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.sqlite.db.SupportSQLiteDatabase;
@Database(entities = {User.class},version = 1,exportSchema = false)
public abstract class UserDatabase extends RoomDatabase {
    public static final String DB_NAME = "UserDataBase.db";
    private static volatile UserDatabase instance;
    public static synchronized UserDatabase getInstance(Context context){
        if (instance == null){
            instance = createDatabase(context);
        }
        return instance;
    }
    private static UserDatabase createDatabase(Context context) {
        return Room.databaseBuilder(context,UserDatabase.class,DB_NAME).allowMainThreadQueries().addCallback(new RoomDatabase.Callback(){
            @Override
            public void onCreate(@NonNull SupportSQLiteDatabase db) {
                super.onCreate(db);
            }
            @Override
            public void onOpen(@NonNull SupportSQLiteDatabase db) {
                super.onOpen(db);
            }
        }).build();
    }
    public abstract UserDao getUserDao();
}

数据库相关的逻辑已经编写完毕,可以通过

 UserDatabase.getInstance(mContext).getUserDao().insert(user);

来给数据库添加数据。

下面是AIDL相关:

将视图切换到Project目录下,右键点击项目创建AIDL文件。

给service添加一个隐式意图的action,以方便另外一个app可以找到这个service。

到这里服务端APP搞定了,下面编写客户端APP的代码。

新建工程,将aidl整个包拷贝到新app的对应位置,包名必须一致。同样需要拷贝的还有数据bean User.java。这里同样这个类所在的包必须和服务端User类所在的包名一模一样。比如我服务端User类在com.example.testapp.database包下,那么我就需要在客户端app下也创建一个一样的包把User类放进去。

在这里插入图片描述
在这里插入图片描述

现在我们就可以去调用服务端的Service了。

简单编写一个Activity,在Activity中使用TextView显示数据库中所有User的name。

package com.example.test2app;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.example.testapp.database.DBAidlInterface;
import com.example.testapp.database.User;
import java.util.List;
public class MainActivity extends AppCompatActivity {
    private DBAidlInterface aidlInterface;
    private TextView textView;
    private Context mContext;
    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            aidlInterface = DBAidlInterface.Stub.asInterface(service);
            Toast.makeText(mContext,"已连接",Toast.LENGTH_LONG).show();
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            aidlInterface = null;
            Toast.makeText(mContext,"断开连接",Toast.LENGTH_LONG).show();
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = findViewById(R.id.text_view);
        mContext = this;
    }
    @Override
    protected void onStart() {
        super.onStart();
        Intent intent =new Intent();
        //Android现在对隐式意图管理严格,除了要setAction包名也需要设置,这里包名是服务端app的包名
        intent.setAction("com.example.testapp.aidl");
        intent.setPackage("com.example.testapp");
        //绑定服务
	    bindService(intent,mConnection,Context.BIND_AUTO_CREATE);
    }
    @Override
    protected void onResume() {
        super.onResume();
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //解绑服务
        unbindService(mConnection);
    }
	//Button OnClick方法
    public void getData(View view) {
        if (aidlInterface!=null){
            try {
                List users = aidlInterface.getUsers();
                String str = "";
                for (User user: users){
                    str = str + user.getName()+" ";
                }
                textView.setText(str);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }else {
        }
    }
}

将两个APP都安装到手机上,在服务端APP上添加数据库数据,切换到客户端app上点击按钮就能拿到最新的数据了。

扩展

想到这个例子主要是之前看Content Provider的时候发现网上操作Content Provider的例子几乎都是使用的原生SQLiteOpenHelper的,并没有结合GreenDao,Room这种sqlite框架或者Realm数据库来使用,使用起来不是很方便。ContentProvider也是Android跨进程数据共享方案,和AIDL一样底层都是Binder机制,就想着能不能用AIDL来跨进程访问数据库,现在看来是可以的。但是有一个问题,客户端在绑定Service的时候需要服务端的进程是活着的。所以在启动前需要先唤醒服务端进程或者给服务端做保活才稳定。还是Content Provider好用~


作者:祁门路搅屎王


--结束END--

本文标题: Android使用AIDL共享Room数据库

本文链接: https://www.lsjlt.com/news/29586.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 【Android】Room数据库的使用
    简介 Room 是在 SQLite 的基础上推出的 Android 库,它是 Google 官方对数据库操作的推荐方式。使用 Room 可以更方便、高效地操作 SQLite 数据库。 使用 添加依赖 ...
    99+
    2023-09-06
    android 数据库
  • Android room数据库使用详解
    1、引入库 def room_version = "2.3.0" implementation "androidx.room:room-runtime:$room_ve...
    99+
    2024-04-02
  • Android Room数据库加密详解
    本文实例为大家分享了Android Room之数据库加密的具体实现,供大家参考,具体内容如下 一、需求背景 Android平台自带的SQLite有一个致命的缺陷:不支持加密。这就导致...
    99+
    2024-04-02
  • Android数据共享 sharedPreferences 的使用方法
    Android数据共享 sharedPreferences 的使用方法Android 中通过 sharedPreferences 来持久化存储数据并进行共享在 Activity 或存在 Context 环境中即可使用context.getS...
    99+
    2023-05-30
    android sharedpreferences roi
  • 共享数据库连接
    一分耕耘,一分收获!既然都打开这篇《共享数据库连接》,就坚持看下去,学下去吧!本文主要会给大家讲到等等知识点,如果大家对本文有好的建议或者看到有不足之处,非常欢迎大家积极提出!在后续文章我会继续更新...
    99+
    2024-04-05
  • Android Room数据库加密的示例分析
    这篇“Android Room数据库加密的示例分析”除了程序员外大部分人都不太理解,今天小编为了让大家更加理解“Android Room数据库加密的示例分析”,给大家总结了以下内容,具有一定借鉴价值,内容详细步骤清晰,细...
    99+
    2023-06-26
  • 使用Java怎么操作共享数据
    这篇文章将为大家详细讲解有关使用Java怎么操作共享数据,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Java可以用来干什么Java主要应用于:1. web开发;2. Android开发;3...
    99+
    2023-06-14
  • android跨进程共享数据怎么实现
    Android中跨进程共享数据可以使用以下方法实现:1. 使用Binder机制:Binder是Android中一种轻量级的进程间通信...
    99+
    2023-10-10
    android
  • Android Jetpack 从使用到源码深耕【数据库注解Room 从实践到原理 】(一)
    android 开发中,常见的数据存储的方式,有SharePreference、网络、Sqlite、MMKV、文件、 ContentProvider,其中,SharePreference、MMKV从简单的使用入手,到使用上的经验总结,最...
    99+
    2023-08-20
    数据库 android jetpack android Room 源码原理
  • 怎么使用ZeroMQ消息库在C和Python间共享数据
    本篇内容介绍了“怎么使用ZeroMQ消息库在C和Python间共享数据”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!ZeroMQ 提供了一个...
    99+
    2023-06-16
  • 如何在PHP中使用数据共享函数
    随着互联网技术的发展,数据共享变得越来越重要。在PHP中,我们也有很多方法来实现数据共享。本文将介绍几种常见的PHP数据共享函数,并提供使用实例。一、共享数据的概念在PHP中,数据共享指的是将一些数据存储在一个地方(比如文件或内存)中,在不...
    99+
    2023-05-18
    函数 PHP 数据共享
  • nginx怎么使用ctx实现数据共享
    这篇文章主要介绍了nginx怎么使用ctx实现数据共享的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇nginx怎么使用ctx实现数据共享文章都会有所收获,下面我们一起来看看吧。...
    99+
    2024-04-02
  • Android Jetpack 从使用到源码深耕【数据库注解Room 从实践到原理 】(二)
    上文,我们通过一个简单的sqlite应用实例,引入了Room,知道了Room使用的便捷和好处。然后用Room的方式,重新实现了应用实例中的场景,在这个过程中,我们结合自己已有的知识体系,从使用代码入手,对Room的实现原理,进行了猜想和...
    99+
    2023-08-16
    数据库 android jetpack java Room 原理源码
  • Android Jetpack 从使用到源码深耕【数据库注解Room 从实践到原理 】(三)
    前面两篇文章,我们一起学习了,Room引入的背景、Room的使用方式、Room的实现原理猜想验证、Room的源码原理探索总结。 本文,我们将其中牵扯到的课外知识点 or 过程中没有说到的知识点,进行一下单独的总结。 题外话:扩展知识点...
    99+
    2023-08-17
    android jetpack 数据库 rxjava Room 原理源码
  • openGauss数据库共享存储特性概述
    目录版本介绍继承功能:新增功能:主备共享存储特性简介客户价值特性描述特性约束openGauss 3.1.1是openGauss 5.0.0 release版本的Preview版本,希望广大社区伙伴和开发者基于此版本进行场...
    99+
    2023-02-18
    openGauss数据库共享存储 openGauss共享存储 openGauss数据库存储
  • Vue局部组件数据共享Vue.observable()的使用
    随着组件的细化,就会遇到多组件状态共享的情况, Vuex当然可以解决这类问题,不过就像 Vuex官方文档所说的,如果应用不够大,为避免代码繁琐冗余,最好不要使用它,今天我们介绍的是 ...
    99+
    2024-04-02
  • Android之SQLite数据库使用
    文章目录 简介关键类SQLiteOpenHelper创建数据库数据库操作insert增加数据update方法更新记录使用delete方法删除记录使用query方法查询记录 简介 SQLite是Android系统集成的一个轻量...
    99+
    2023-08-18
    数据库 sqlite android
  • android数据库怎么使用
    在Android中,可以使用SQLite数据库进行数据存储和检索。以下是使用Android数据库的一般步骤:1. 创建数据库:在An...
    99+
    2023-08-17
    android 数据库
  • Android数据库操作工具类分享
    本文实例为大家分享了Android数据库操作工具类的具体代码,供大家参考,具体内容如下HistoryDAOpublic class HistoryDAO { private DBConnection dbc = null; privat...
    99+
    2023-05-30
    android 数据库 工具类
  • 数据库内存共享实现原理是什么
    这篇文章主要讲解了“数据库内存共享实现原理是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“数据库内存共享实现原理是什么”吧!共享内存是进程间通讯的一种方...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作