在Android上配置gRPC的环境

1.下载安装Protobuf Support插件,如图所示:

2.在项目根目录的 build.gradle 的 buildscript 中加入 protobuf-gradle-plugin 插件:

buildscript {
    ...
    dependencies {
        ...
        classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.12"
    }
}

3.在应用Module的 build.gradle 中进行如下配置

apply plugin: 'com.android.application'
apply plugin: 'com.google.protobuf'

protobuf {
    protoc { artifact = 'com.google.protobuf:protoc:3.11.0' }
    plugins {
        grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.29.0' }
    }
    generateProtoTasks {
        all().each { task ->
            task.builtins {
                java { option 'lite' }
            }
            task.plugins {
                grpc { option 'lite' }
            }
        }
    }
}

dependencies {
    // gRPC
    implementation 'io.grpc:grpc-okhttp:1.29.0'
    implementation 'io.grpc:grpc-protobuf-lite:1.29.0'
    implementation 'io.grpc:grpc-stub:1.29.0'
    implementation 'javax.annotation:javax.annotation-api:1.2'
}

4.最后将 .proto 协议文件放在 src/main/proto/ 文件夹下,点击build进行编译,如果出现如下图,则证明环境配置成功!


参考链接:

教你如何使用ProtoBuf,通过gRPC服务在android上进行网络请求。

gRPC快速入门

GRPC原理解析

官方示例

【转】Java Thread的关于Join,wait,sleep的解释

转载自:Java Thread的关于Join,wait,sleep的解释


Java线程中的Thread.wait()方法
说句实话,在Thread中,我wait方法我从来没有用过,当线程需要休息时,我只是用到了sleep。今天花了点时间研究了一些wait和join方法。

首先,学习要从追问开始。
wait()这个方法它的功能是什么?它的功能是使当前线程阻塞以等待另外一个线程的方法。只有等待的线程里,调用了notify的方法,当前线程便会继续进行。

关于wait()方法,我认为以下这一点概念最为重要:
一:下面这段代码,并且不是使thread1线程阻塞,而是阻塞当前线程,去等待thread1线程调用nofity方法,要注意一开始我一直理解成thread1线程阻塞。

synchronized(thread1){
    thread1.wait();
}

其实只要理解了上面的概念,几乎已经理解wait方法的精髓,还剩一些小概念。
一、wait(long timeout); 这个方法的意思便是,阻塞当前线程timeout毫秒,如果在timeou毫秒之后被等待的线程没有调用notify方法,则结束阻塞。

二、当前每一个线程执行完之后,在C++层,会自动调用了notify。也就是说,假如我们等待的线程执行完毕了,当前等待的线程会自动结束阻塞。

三、wait需要在锁之内被调用。这一块我觉得这片文章写到点上了:https://blog.csdn.net/qq_39907763/article/details/79301813,经过测试,锁只能锁当前的线程的对象,锁其他对象会报监视器异常。

关于notify()方法
notify方法的意思就是,就是通知在等待的线程,你们可以执行的。假如有多个线程调用wait()而阻塞,则他们会相互竞争出一个。

关于notifyAll()方法
notifiyAll就是通知所有调用wait()而阻塞的线程,都继续进行

关于join方法
关于join方法,其实本质上就是判断了一些条件之后调用了wait(0),只要把wait方法理解透了,join自然就理解了。

Kotlin —— 这次入门就不用放弃了

节选自:Kotlin —— 这次入门就不用放弃了


写在文前

本文将展示在Android中会遇到的实际问题,并且使用Kotlin怎么去解决它们。一些Android开发者在处理异步、数据库或者处理Activity中非常冗长的listener时发现了很多的问题。通过一个个真实的场景,我们一边解决问题一边学习Kotlin的特性。

快速上手

如果不知道如何在Kotlin中写一个相当简单的Java表达式。这里有一个简单的诀窍,就是在AndroidStudio的Java文件中编写一段代码,然后将其粘贴到kt文件中,它会自动转换为Kotlin。

Kotlin优势

  1. 它更加易表现:这是它最重要的优点之一。你可以编写少得多的代码。
  2. 它更加安全:Kotlin是空安全的,也就是说在我们编译时期就处理了各种null的情况,避免了执行时异常。你可以节约很多调试空指针异常的时间,解决掉null引发的bug。
  3. 它可以扩展函数:这意味着,就算我们没有权限去访问这个类中的代码,我们也可以扩展这个类的更多的特性。
  4. 它是函数式的:Kotlin是基于面向对象的语言。但是就如其他很多现代的语言那样,它使用了很多函数式编程的概念,比如,使用lambda表达式来更方便地解决问题。其中一个很棒的特性就是Collections的处理方式。我稍后会进行介绍。
  5. 它是高度互操作性的:你可以继续使用所有用Java写的代码和库,甚至可以在一个项目中使用Kotlin和Java两种语言混合编程。一行Java一行Kotlin,别提有多风骚了。

开始使用Kotlin协程

节选自:开始使用Kotlin协程


本文主要介绍协程的用法, 以及使用协程能带来什么好处. 另外, 也会粗略提一下协程的大致原理.
本文的意义可能仅仅是让你了解一下协程, 并愿意开始使用它.
如果想彻底理解协程, 请查看官方文档, 官方文档链接将在文章的结尾给出.

如果你以前在别的语言里学习过协程, 如Python的yield, 那请你先忘记它们, 毕竟还是有些区别, 等你弄懂了Kotlin的协程, 再去作对比, 否则, 可能会有一些先入为主的思路来阻碍你理解, 我就吃过这个亏.

初识协程:

首先我们来瞄一眼协程是长啥样的, 以下引用(copy)了官网的一个例子:

fun main(args: Array<String>) {
    launch(CommonPool) {
        delay(1000L) 
        println("World!") 
    }
    println("Hello,")
    Thread.sleep(2000L)
}

/* 
运行结果: ("Hello,"会立即被打印, 1000毫秒之后, "World!"会被打印)
Hello, 
World!
*/

姑且不管里面具体的细节, 上面代码大体的运行流程是这样的:

A. 主流程:

1.调用系统的launch方法启动了一个协程, 跟随的大括号可以看做是协程体.
(其中的CommonPool暂且理解成线程池, 指定了协程在哪里运行)
2.打印出”Hello,”
3.主线程sleep两秒
(这里的sleep只是保持进程存活, 目的是为了等待协程执行完)

B. 协程流程:

1.协程延时1秒
2.打印出”World!”

解释一下delay方法:
在协程里delay方法作用等同于线程里的sleep, 都是休息一段时间, 但不同的是delay不会阻塞当前线程, 而像是设置了一个闹钟, 在闹钟未响之前, 运行该协程的线程可以被安排做了别的事情, 当闹钟响起时, 协程就会恢复运行.

Kotlin/JVM 协程实现原理

节选自:Kotlin/JVM 协程实现原理


目录

前言

在文章正式上干货之前,先说一点背景吧;我是 Kotlin 协程官方文档的译者,大家在 Kotlin 中文官网上看到的绝大多数协程的中文官方文档都是我翻译的。

官方文档可以说是比较全面的介绍了协程的使用,但是就我的感觉来说,这些文档分布的比较散乱,甚至还有三篇分布在协程的官方 Github 的 project 中,很多协程的初学者对这些文档的阅读顺序也常常感到摸不到头脑。这里我将一共 15 篇文档的学习顺序做一个整理,如果你还不了解如何使用协程,可以参考我如下的列举:

首先,如果您不了解什么是协程,以及不清楚如何将协程引入您的项目,你可以按顺序阅读这两篇教程:

接下来两篇官方文档类似于导读或目录,简述了一下协程的理念,以及给出了一些干货的链接,这两篇导读本身倒是没啥干货:

然后就是大量的正餐了,如下九篇官方文档介绍了协程使用的方方面面,一定要读懂:

上面九篇文档读完,再配以大量的实践,你应该已经掌握了协程的基本用法,并开始思考使用它的场景,你可能想知道如何使用协程编写 UI 应用程序,亦或是你可能对协程和响应式流(例如 RxJava)之间的异同和关系有疑问,那么可以参考下面两篇被刊登在官方 Github 上的指南:

现在你应该已经掌握协程在绝大多数场景下的用法,于是你可能好奇于它的实现原理,那么可以阅读这篇官方 Keep:

目前这就是协程全部的官方资料,两篇指南和一篇 Keep,都是刊登在 Github 上的;目前 Kotlin 中文站的站长是灰蓝天际老哥,所以上面给出的指向 Github 的地址是指向他 Fork 的版本,以上所有文档的英文原版,都可以在 Kotlin 的英文官网,以及官方的 Github 上找到。

Kotlin 目前是一门多平台语言,虽然协程的设计思想是统一的,但它们在底层的实现原理上会有所不同,例如,在 JVM 和 Android 上,协程的实现要基于线程池的 API,但是在 JS 平台上,由于 JS 本身不支持多线程,所以协程这时必定就不会产生并行。作为一名 Android 工程师,本文将致力于阐述协程在 Android 平台和 JVM 平台的原理,而 JS 平台以及众多的 Native 平台则暂不讨论。

本文将会先介绍一些协程的设计思想,然后详细讲解一下协程的编译相关以及标准库等内容,然后根据源码深入到协程调度器的底层实现细节(调度器这一部分我认为是最值得去看的)。

【转】Android EditText设置负数以及小数

转载自:Android Edittext设置负数以及小数


1,设置Edittext只可以输入数字,只需要给EditText这样设置

xml:
android:inputType="number"
代码中设置:
edit.setInputType(InputType.TYPE_CLASS_NUMBER);

2,设置Edittext可以输入正负数字,需要给EditText这样设置

xml:
android:inputType="numberSigned"
代码中设置:
edit.setInputType(InputType.TYPE_CLASS_NUMBER|InputType.TYPE_NUMBER_FLAG_SIGNED);

3,设置Edittext可输入带小数点的数字,需要给EditText这样设置

xml:
android:inputType="numberDecimal"
代码中设置:
edit.setInputType(InputType.TYPE_CLASS_NUMBER|InputType.TYPE_NUMBER_FLAG_DECIMAL);

4,设置Edittext可输入正负带小数点的数字,需要给EditText这样设置

xml:
android:inputType="numberSigned|numberDecimal"
代码中设置:
edit.setInputType(InputType.TYPE_CLASS_NUMBER|InputType.TYPE_NUMBER_FLAG_SIGNED|InputType.TYPE_NUMBER_FLAG_DECIMAL);