安卓项目搭建grpc环境
本篇文章使用的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 32defaultConfig {applicationId "com.example.grpc_project_plus"minSdk 29targetSdk 32versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility 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_outoption '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_VERSIONimplementation 'io.grpc:grpc-protobuf-lite:1.39.0' // CURRENT_GRPC_VERSIONimplementation 'io.grpc:grpc-stub:1.39.0' // CURRENT_GRPC_VERSIONimplementation '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 greetingrpc 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";@Overrideprotected 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>() {@Overridepublic void onNext(HelloReply value) {//Log.d(TAG, "sayHello onNext.");Log.d(TAG, value.getMessage());}@Overridepublic void onError(Throwable t) {Log.d(TAG, "sayHello onError.");}@Overridepublic 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"/><applicationandroid: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"><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter><meta-dataandroid:name="android.app.lib_name"android:value="" /></activity></application></manifest>
运行上述代码,如果能在控制台看到下面的这句话就说明环境搭建成功了。

结语
这次的环境搭建真的非常艰难,前前后后遇到了各种问题。不得不说,安卓编程对于版本太敏感了,只要有一个版本没有对应上项目都可能跑不通。
如果你遇到了什么问题欢迎在评论区交流,大家一起总结问题,少踩坑,共勉!
相关文章:
安卓项目搭建grpc环境
本篇文章使用的IDE是Android Studio。这里先吐槽一句,安卓项目搭建grpc环境,不管是引入插件还是引入第三方库,对于版本的要求都极为苛刻,一旦版本不匹配就会报错,所以对于版本的搭配一定要注意。 下面介绍的这个版本搭…...
Flink01: 基本介绍
一、什么是Flink 1. Flink是一个开源的分布式,高性能,高可用,准确的流处理框架 (1)分布式:表示flink程序可以运行在很多台机器上, (2)高性能:表示Flink处理性…...
设计模式之单例模式
文章の目录一、什么是单例模式二、如何实现单例模式1、利用JavaScript中的全局对象2、静态成员改造参考写在最后一、什么是单例模式 单例模式也称为单体模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点。 举个栗子:一个班级只有一…...
[oeasy]python0086_ASCII_出现背景_1963年_DEC_PDP系列主机_VT系列终端
编码进化 回忆上次内容 上次 回顾了 字符编码的新陈代谢 ibm 曾经的EBCDIC 由于 字符不连续导致 后续 出现无数问题 随着 网络的发展 数据交换的 需要原来的小隐患现在 产生了 巨大问题 Bemer 联合各方巨头 想要推出 字符连续的编码集 这新编码集 具体长什么样 呢࿱…...
基于FFmpeg实现的无声音屏幕录制
UI自动化测试时,有时需要进行录屏操作,这时我们是不需要声音的,我们可以通过FFmpeg进行简单的录制工作。 以下是在windows10环境下,基于FFmpeg实现的简单录制: Ffmpeg简介: 功能:有非常强大的…...
【项目精选】基于JSP物流信息网(论文+源码+视频)
点击下载源码 近年来,随着时代的进步,社会随之不断发展,经济也快速发展起来了,人民的消费水平在不断地提高,平常的实体店消费已经不能满足人们的需求;在者,互联网技术的不断发展也为电子商务的兴…...
linux异步IO编程实例分析
在Direct IO模式下,异步是非常有必要的(因为绕过了pagecache,直接和磁盘交互)。linux Native AIO正是基于这种场景设计的,具体的介绍见:KernelAsynchronousI/O (AIO)SupportforLinux。下面我们就来分析一下…...
日常英语口语练习-情景交际场景25(三)
登山踏青m: hey Carol, what are you doing this weekend?o: im going hiking /haikiŋ/登山with my husband and our hiking clubm: you have a hiking culb?o: yes, we do, we have 30 to 40 people of all ages and skill levelsm: thats great, do you gus do…...
Qt 工程师进阶技术23种设计模式
Qt 工程师进阶技术23种设计模式【1】23种设计模式【1】23种设计模式 设计模式是解决特定问题的一系列套路,这套方案提高代码可复用性、可读性、稳健性、可维护性及安全性。 23种设计模式可分为三类:结构型模式(侧重类与对象之间的组合)、行为型模式(侧重…...
Redis 强化
(Redis入门使用查看)https://blog.csdn.net/weixin_73849581/article/details/128390152?spm1001.2014.3001.5501缓存使用原则什么时候,什么样的数据能够保存在Redis中?1.数据量不能太大2.使用越频繁,Redis保存这个数据越值得3.保存在Redis中的数据一般不会是数据库中频繁修改…...
华为OD机试题 - 众数和中位数(JavaScript)
最近更新的博客 华为OD机试题 - 任务总执行时长(JavaScript) 华为OD机试题 - 开放日活动(JavaScript) 华为OD机试 - 最近的点 | 备考思路,刷题要点,答疑 【新解法】 华为OD机试题 - 最小步骤数(JavaScript) 华为OD机试题 - 任务混部(JavaScript) 华为OD机试题 - N 进…...
Go: expected pseudo-register found R13 error
报错描述: 启动Go项目时,报错: ../../../.go/pkg/mod/github.com/choleraehyq/pidv0.0.10/pid_go1.5_amd64.s:28: expected pseudo-register; found R13 原因分析: github.com/choleraehyq/pid这个依赖包的版本太低,需…...
程序员必备的技能-深入理解 Linux 内核拆解
841 页的《深入理解 Linux内核》堪称经典,时隔多年打开,泛黄的纸张上面仍然跳跃出一个个让人心潮澎湃的知识点,突然让我想起一位微信朋友的昵称:知识的舔狗!拆,开始~前言第一章 绪论Linux与其他类Unix内核…...
学习 Python 之 Pygame 开发坦克大战(三)
学习 Python 之 Pygame 开发坦克大战(三)坦克大战物体碰撞检测编写1. 实现敌方坦克与我方坦克间的碰撞2. 实现敌方坦克间的碰撞3. 实现玩家子弹与敌方坦克间的碰撞4. 实现敌方子弹与我方坦克间的碰撞 和 玩家复活5. 爆炸效果类6. 为子弹爆炸添加爆炸效果…...
Docker 学习笔记
概述 1. 什么是 Docker? Docker 是一个应用容器平台,管理项目中用到的所有环境(MySQL、Redis…) 2. Docker 和虚拟机的区别 虚拟机是携带操作系统的,本身很小的应用程序因为携带了操作系统而变得十分笨重࿰…...
华为OD机试 - 相同数字的积木游戏1(JS)
相同数字的积木游戏1 题目 小华和小薇一起通过玩积木游戏学习数学。 他们有很多积木,每个积木块上都有一个数字, 积木块上的数字可能相同。 小华随机拿一些积木挨着排成一排,请小薇找到这排积木中数字相同且所处位置最远的2块积木块,计算他们的距离。 小薇请你帮忙替她解…...
Linux系统之iptables应用SNAT与DNAT
目录 SNAT 一.SNAT的原理介绍 1.应用环境 2.SNAT原理 3.SNAT转换前提条件 二.开启SNAT 1.临时打开 2.永久打开 三.SNAT的转换 1.固定的公网IP地址 2.非固定的公网IP地址(共享动态IP地址) 四.SNAT实验 1.实验环境准备 2.配置web服务器(192.168.100.100…...
2023美赛ABCDEF思路汇总
注:以下每个题思路仅是个人所想所做,不代表他人。由于时间仓促完成这么多,难免有不足之处,还请谅解。 文章目录A题第一大问第二大问B题第一问第二问第三问C题第一问第二问第三问第四问D题第一问第二问第三问第四问第五问E题第一问…...
Damask和abaqus晶体塑性联合仿真培训通知
一 软件介绍 DAMASK 是一个统一的多物理晶体塑性模拟包。连续体力学边值问题的求解需要连接每个材料点的变形和应力的本构响应,该问题在 DAMASK 中基于晶体可塑性使用各种本构模型和均质化方法能够被有效解决。除此之外,孤立地处理力学已不足以研究新兴的先进高强度…...
用javascript分类刷leetcode17.栈(图文视频讲解)
目录 Stack的特点:先进后出(FILO) 使用场景:十进制转2进制 函数调用堆栈 js里没有栈,但是可以用数组模拟 42/2 42%20 21/2 21%21 10/2 10%20 5/2 5%21 2/2 2%20 1/2 1%21 stack: [0,1,0,1,0,1] res: 1 0 1 …...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...
