安卓项目搭建grpc环境

news2024/11/15 4:57:32

本篇文章使用的IDE是Android Studio。这里先吐槽一句,安卓项目搭建grpc环境,不管是引入插件还是引入第三方库,对于版本的要求都极为苛刻,一旦版本不匹配就会报错,所以对于版本的搭配一定要注意。

下面介绍的这个版本搭配是我研究好久好久才跑通的,这在我的电脑上是一组可行的配置,如果你使用了同样的配置跑不通,那可能是环境中某一部分还是有不同的地方,需要你自己再去找一下解决问题的办法,那么话不多说,直接上配置吧。

各种配置文件

首先我们需要设置三个配置文件,如下图所示

我们先来看一下项目设置setting.gradle,按照我的理解,这里应该是设置一些gradle仓库地址,还有项目中包含的模块等等信息。

我的配置是这样写的

pluginManagement {
    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()

        maven { url 'https://jitpack.io' }
        maven { url 'https://repo.eclipse.org/content/repositories/paho-releases/'}

    }
}
rootProject.name = "grpc_project_plus"
include ':app'

接着是项目的的build.gradle,这里面需要引入一些插件和进行gradle版本设置,其中gradle版本设置也是一个坑,版本号要设置对才行

buildscript {
    repositories {
        maven{ url 'https://maven.aliyun.com/repository/jcenter'}
        maven { url 'https://maven.aliyun.com/repository/google' }
        maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
        maven { url 'https://maven.aliyun.com/repository/public' }
        google()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:7.2.0"
        classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.17"

    }
}


task clean(type: Delete) {
    delete rootProject.buildDir
}

从上面的配置中我们可以看出,我们使用的gradle插件的版本是7.2.0,然后配置的gradle版本是7.4,具体的设置方法就是到gradle的配置文件中指定

当然也有一个简单的办法,就是到project structure中去指定

上面这张图按照我的理解,上面是插件的版本号,下面就是gradle的版本号,这两个不对应的话容易出问题,这里顺便说一下,我的Android Studio的版本应该是2021.3.1,就是海豚的图标。(经过这次的环境搭建,我现在对于版本号真的非常敏感,调版本号真的太折磨人了)

最后就是模块的build.gradle,我找到的一个能跑通demo的设置如下

plugins {
    id 'com.android.application'
    id 'com.google.protobuf'
}

android {
    namespace 'com.example.grpc_project_plus'
    compileSdk 32

    defaultConfig {
        applicationId "com.example.grpc_project_plus"
        minSdk 29
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    configurations.all {
        resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.1'
        exclude group: 'com.google.guava', module: 'listenablefuture'
    }

    sourceSets {
        main {
            proto {
                srcDir 'src/main/proto'
            }
        }
    }

    packagingOptions {
        pickFirst 'META-INF/INDEX.LIST'
        pickFirst 'META-INF/LICENSE'
        pickFirst 'META-INF/io.netty.versions.properties'
    }
}

protobuf {
    protoc {
        artifact = 'com.google.protobuf:protoc:3.17.2'
    }
    plugins {
        /*javalite {
            artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0"
        }*/
        grpc {
            artifact = 'io.grpc:protoc-gen-grpc-java:1.39.0' // CURRENT_GRPC_VERSION
        }
    }
    generateProtoTasks {
        all().each { task ->
            task.builtins {
                java { option 'lite' }
            }
            task.plugins {
                grpc { // Options added to --grpc_out
                    option 'lite' }
            }
        }
    }
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.5.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'


    /*implementation 'io.grpc:grpc-okhttp:1.1.2'
    implementation 'io.grpc:grpc-netty:1.1.2'
    implementation 'io.grpc:grpc-protobuf-lite:1.1.2'
    implementation 'io.grpc:grpc-stub:1.1.2'
    implementation 'javax.annotation:javax.annotation-api:1.2'*/
    // You need to build grpc-java to obtain these libraries below.
    implementation 'io.grpc:grpc-netty:1.39.0'
    implementation 'io.grpc:grpc-okhttp:1.39.0' // CURRENT_GRPC_VERSION
    implementation 'io.grpc:grpc-protobuf-lite:1.39.0' // CURRENT_GRPC_VERSION
    implementation 'io.grpc:grpc-stub:1.39.0' // CURRENT_GRPC_VERSION
    implementation 'org.apache.tomcat:annotations-api:6.0.53'
}

编写proto文件并编译

配置好了上述环境后,我们需要编译proto文件。

首先在main目录下新建一个文件夹proto,然后编写hello.proto文件。

文件的内容如下

syntax = "proto3";

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";

package helloworld;

// The greeting service definition.
service Greeter {
    // Sends a greeting
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
    string name = 1;
}

// The response message containing the greetings
message HelloReply {
    string message = 1;
}

这是一个简单的grpc接口调用,具体的语法我就不说了,这篇文章主要是讲环境搭建。

接着编译项目,如果编译成功的话,可以在build文件夹中看到grpc相关的java文件。

编写简单的demo代码

这是最后一步,在主Activity中编写简单的客户端和服务端代码测试grpc服务是否可以正常使用。

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "GrpcDemo";

    private static final int PROT = 56322;
    private static final String NAME = "hello world";
    private static final String HOST = "localhost";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "start");
        startServer(PROT);
        Log.d(TAG, "start server.");
        startClient(HOST, PROT, NAME);
        Log.d(TAG, "start client.");
    }

    private void startServer(int port){
        try {
            NettyServerBuilder.forPort(port)
                    .addService(new GreeterImpl())
                    .build()
                    .start();
        } catch (IOException e) {
            e.printStackTrace();
            Log.d(TAG, e.getMessage());
        }
    }

    private void startClient(String host, int port, String name){
        ManagedChannel mChannel = ManagedChannelBuilder.forAddress(host, port)
                .usePlaintext()
                .build();
        GreeterGrpc.GreeterStub stub = GreeterGrpc.newStub(mChannel);
        HelloRequest message = HelloRequest.newBuilder().setName(name).build();
        stub.sayHello(message, new StreamObserver<HelloReply>() {
            @Override
            public void onNext(HelloReply value) {
                //Log.d(TAG, "sayHello onNext.");
                Log.d(TAG, value.getMessage());
            }

            @Override
            public void onError(Throwable t) {
                Log.d(TAG, "sayHello onError.");
            }

            @Override
            public void onCompleted() {
                Log.d(TAG, "sayHello onCompleted.");
            }
        });
    }

    private class GreeterImpl extends GreeterGrpc.GreeterImplBase {
        public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) {
            responseObserver.onNext(sayHello(request));
            responseObserver.onCompleted();
        }

        private HelloReply sayHello(HelloRequest request) {
            return HelloReply.newBuilder()
                    .setMessage(request.getName())
                    .build();
        }
    }

}

然后需要在AndroidManifest.xml文件中添加网络权限

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

    <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Grpc_project_plus"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
    </application>

</manifest>

运行上述代码,如果能在控制台看到下面的这句话就说明环境搭建成功了。

结语

这次的环境搭建真的非常艰难,前前后后遇到了各种问题。不得不说,安卓编程对于版本太敏感了,只要有一个版本没有对应上项目都可能跑不通。

如果你遇到了什么问题欢迎在评论区交流,大家一起总结问题,少踩坑,共勉!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/356583.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CMake中cmake_host_system_information的使用

CMake中的cmake_host_system_information命令用于查询各种主机系统信息&#xff0c;其格式如下&#xff1a; cmake_host_system_information(RESULT <variable> QUERY <key> ...) # 1 cmake_host_system_information(RESULT <variable>QUERY WINDOWS_REGIST…

【爬虫理论实战】详解常见头部反爬技巧与验证方式 | 有 Python 代码实现

以下是常见头部反爬技巧与验证方式的大纲&#xff1a; User-Agent 字段的伪装方式&#xff0c;Referer 字段的伪装方式&#xff0c;Cookie 字段的伪装方式。 文章目录1. ⛳️ 头部反爬技巧1.1. User-Agent 字段&User-Agent 的作用1.2. 常见 User-Agent 的特征1.3. User-Age…

Spring IoC容器之常见常用注解以及注解编程模型简介

一、全文概览 本篇文章主要学习记录Spring中的核心注解&#xff0c;罗列常见常用的注解以及Spring中的注解编程模型介绍 二、核心注解 1、Spring模式注解 常用注解场景描述Spring起始支持版本Component通用组件模式注解&#xff0c;是所有组件类型注解的元注解Spring 2.5Repo…

【分库分表】企业级分库分表实战方案与详解(MySQL专栏启动)

&#x1f4eb;作者简介&#xff1a;小明java问道之路&#xff0c;2022年度博客之星全国TOP3&#xff0c;专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化&#xff0c;文章内容兼具广度、深度、大厂技术方案&#xff0c;对待技术喜欢推理加验证&#xff0c;就职于…

计算机操作系统概述

文章目录1.0 操作系统概述1.1 操作系统的目标1.2 操作系统的功能1.3 操作系统结构1.4 操作系统接口1.5 操作系统的发展1.6 操作系统的特征2.0 进程管理2.1 进程调度2.2 进程调度算法2.3 进程间通信2.4 进程间的同步2.5 软件实现互斥的方法2.6 硬件实现互斥的方法2.7 信号2.8 管…

python基于django 医院急诊挂号系统

目录 1 绪论 1 1.1课题背景 1 1.2课题研究现状 1 1.3初步设计方法与实施方案 2 1.4本文研究内容 2 2 系统开发环境 4 2.1 JAVA简介 4 2.2MyEclipse环境配置 4 2.3 B/S结构简介 4 2.4MySQL数据库 5 2.5 SPRINGBOOT框架 5 3 系统分析 6 3.1系统可行性分析 6 3.1.1经济可行性 6 3.…

Mysql(二)索引、查询

索引一、索引索引分类MySQL索引结构**B和B-树的区别**语法创建修改删除查看二、MySQL查询一、索引 概念&#xff1a; 索引时帮助MySQL高效获取数据的数据结构 本质&#xff1a; 数据结构 实现&#xff1a; 在存储引擎层面实现的&#xff0c;而不是server层面。不是所有的存储引…

CNI 网络分析(九)Calico IPIP

文章目录环境流量分析Pod 间Node 到 PodPod 到 serviceNode 到 serviceNetworkPolicy理清和观测网络流量环境 可以看到&#xff0c;在宿主机上有到每个 pod IP 的路由指向 veth 设备 到对端节点网段的路由 指向 tunl0 下一跳 ens10 的 ip 有到本节点网段 第一个 ip 即 tunl0 的…

Prometheus监控案例之blackbox-exporter

blackbox-exporter简介 blackbox-exporter项目地址&#xff1a;https://github.com/prometheus/blackbox_exporter blackbox-exporter是Prometheus官方提供的一个黑盒监控解决方案&#xff0c;可以通过HTTP、HTTPS、DNS、ICMP、TCP和gRPC方式对目标实例进行检测。可用于以下使…

基于计算机视觉的建筑物火灾早期探测模型的开发

1.文章信息本次介绍的文章是2023年韩国延世大学作为一作发表的一篇关于基于计算机视觉的火灾检测文章&#xff0c;题目为《Development of early fire detection model for buildings using computer vision-based CCTV》。2.摘要建筑物的火灾直接影响到居住者的生命。因此&…

FL Studio最新发布21版本更新全部内容详情介绍

FL Studio最新发布21版本&#xff0c;也是一次重要的版本更新&#xff0c;让使用FL Studio软件的音乐制作人们进入到了全新的AI编曲时代&#xff0c;并改进了80多操作页面包括用户页面、项目文件夹、常规设置、导出导入等等&#xff0c;使用起来更加的简洁。本期给大家带来的是…

相关性-回忆录(持续更新)

1.TODO方向 &#xff08;1&#xff09;数据增强&#xff1a;finetuning阶段需要大量人工标注样本&#xff0c;消耗时间和成本。用户点击数据作为弱监督学习&#xff0c;可以尝试图网络构建节点和边&#xff08;query聚合&#xff09;&#xff1b; 使用展现未点击生成对抗网络进…

加油站会员管理小程序实战开发教程14 会员充值

我们上篇介绍了会员开卡的业务,开卡是为了创建会员卡的信息。有了会员卡信息后我们就可以给会员进行充值。当然了充值这个业务是由会员自主发起的。 按照我们的产品原型,我们在我的页面以轮播图的形式循环展示当前会员的所有卡信息。这个会员卡信息需要先用变量从数据源读取…

【算法】双指针

作者&#xff1a;指针不指南吗 专栏&#xff1a;算法篇 &#x1f43e;或许会很慢&#xff0c;但是不可以停下来&#x1f43e; 文章目录1.双指针分类2.双指针思想3.双指针应用1.双指针分类 常见问题分类 (1) 对于一个序列&#xff0c;用两个指针维护一段区间, 比如快速排序。 …

SQL代码编码原则和规范

目录1、先了解MySQL的执行过程2、数据库常见规范3、所有表必须使用Innodb存储引擎4、每个Innodb表必须有个主键5、数据库和表的字符集统一使用UTF86、查询SQL尽量不要使用select *&#xff0c;而是具体字段7、避免在where子句中使用 or 来连接条件8、尽量使用数值替代字符串类型…

POI处理Excel (xlsx格式) 设置单元格格式为数值 且千分位分隔 保留两位小数

背景 某公司导出的一个Excel 其中有三列数据 是数字 但是导出后 实际上格式为 数值形式的字符串 客户要求这三列的格式改为 数值格式 且千分位分隔 保留两位小数 分析原因 先看导出用到了什么工具 查看源码发现 导出 使用了 EasyExcel 立马想到 一般情况下导出实体的字段类…

layui框架学习(7:选项卡样式)

选项卡&#xff08;Tab&#xff09;在C/S程序和B/S程序中应用比较广泛&#xff0c;CSDN中也能看到选项卡的身影&#xff08;如下图所示&#xff09;。Layui内置多种Tab风格&#xff0c;支持删除选项卡、并提供响应式支持。Layui官方教程中主要介绍了选项卡相关的样式设置&#…

Windows Server 2016远程桌面配置全过程

镜像下载 系统镜像网址 本次下载的是 Windows Server 2016 (Updated Feb 2018) (x64) - DVD (Chinese-Simplified) 远程桌面配置 Step 1 在开始菜单搜索服务&#xff0c;打开服务器管理器&#xff0c;点击右上角的管理按钮 Step 2 添加角色控制&#xff0c;点击下一步 S…

如何描述建筑在新型电力系统中的基本特征?——现状与展望(刘晓华)

刘晓华等人 | 如何描述建筑在新型电力系统中的基本特征&#xff1f;——现状与展望 2022如何描述建筑在新型电力系统中的基本特征&#xff1f;——现状与展望 摘要 建筑领域是实现碳中和目标的重要部门&#xff0c;未来零碳能源系统中建筑有望成为集能源生产、消费、调蓄“三…

【Redis】一、CentOS64 安装 Redis

1.下载redis https://download.redis.io/releases/2.将 redis 安装包拷贝到 /opt/ 目录 最好自己创建一个文件夹 3.解压 tar -zvxf redis-6.2.1.tar.gz4. 安装gcc yum install gcc5. 进入目录 cd /opt/redis/redis-6.2.1/6. 编译 make7.执行 make install 进行安装 8. …