0%

在ES7中async和await被正式发布,它们是基于Promise的语法糖,可以用于优化链式代码的写法,让代码更具有可读性,编写逻辑更加清晰。

async

async只需要记住两点就可以:

  1. async函数最终都将返回一个Promise对象,返回值通过resolve的参数传递。

    比如这段代码:

    async function test() {
        return "hello js"
    }

    实际上等价于:

    async function test() {
        return Promise.resolve("hello js");
    }

    因此在调用test函数时,可以在then中获取到结果:

    test().then(value => {
      console.log(value);
    })

    所以所有的async函数都不会阻塞当前后面代码的执行,结果需要在then中获取。

  2. await所在的函数必须加上async。

    这个是语法规定的,没什么好说。

Read more »

一、自定义Gradle插件

步骤如下:

  1. 创建空目录,命名HelloPlugin。

  2. 进入HelloPlugin目录下,新建build.gradle,写如下脚本代码:

    apply plugin: 'groovy'
    apply plugin: 'maven'
    
    dependencies {
        implementation gradleApi()
        implementation localGroovy()
    }
    
    repositories {
        google()
        jcenter()
    }
    
    //将插件打包上传到本地maven仓库
    uploadArchives {
        repositories {
            mavenDeployer {
                pom.groupId = 'com.mtan'
                pom.artifactId = 'HelloPlugin'
                pom.version = '1.0.0'
                repository(url: uri('../repos'))
            }
        }
    }
  3. 新增目录src/main/groovy/com/mtan/plugin,新建HelloPlugin.groovy类,代码:

    package com.mtan.plugin;
    
    import org.gradle.api.Plugin
    import org.gradle.api.Project
    
    public class HelloPlugin implements Plugin<Project> {
    
        public void apply(Project project) {
            println 'HelloPlugin apply'
        }
    }
  4. 新建目录src/main/resources/META-INF/gradle-plugins,新增com.mtan.plugin.properties文件,代码:

    implementation-class=com.mtan.plugin.HelloPlugin
  5. 项目导入idea中,执行uploadArchives任务,即可完成插件上传。

Read more »

一、代码修复

1. 原理

原理是比较简单的,本质就是App在运行时,会有个dex数组,当要用到的class不存在时,就顺序从dex数组中寻找,只要找到就停止,因此可以把修复好的dex插入到这个dex数组最前面,那么找的时候就会找到修复好dex中的class,而不再是旧的有问题的class。

2. 动手写代码

Read more »

一、前言

DataBinding库其实出来挺久了,最近工作涉及到跨平台开发,接触到前端的响应式编程,比如微信小程序开发,Vue框架,使用起来还是比较方便的,开发效率也比较高,因此深入分析了Android中的DataBinding库的使用和原理。

二、使用

1. 简单入门

先从最简单的入手,为了让项目支持使用DataBinding,需要在build.gradle中打开开关:

Read more »

Promise用于解决代码嵌套问题,在js中被大量使用,对于如何解决代码嵌套,可以参考之前的文章《使用Promise解决代码嵌套问题》。

要做到熟悉掌握Promise,还需要弄清一些常见的问题,接下来逐一分析。

一、问题:什么时候会执行catch分支?

先从最简单的开始,只有一个Promise函数:

p().then(value => {
    console.log('111');
}, reason => {
    console.log(reason);
}).catch(e => {
    console.log('crash:' + e);
});

function p() {
    return new Promise((resolve, reject) => {
        throw 'hahaha'            
    });
}
Read more »

一、问题

现在有多个请求,第一个请求结束后,失败就结束,成功就继续执行第二个请求,第二个请求结束后,失败就结束,成功就继续执行第三个请求,……,这样一直下去,可能会有三个请求,或者五个请求,或者更多。

二、原有的解决方法

按照以往的思路,会写出如下的嵌套代码:

a(function(res) {
    if (res) {
        console.log('a执行成功');
        b(function(res) {
            if (res) {
                console.log('b执行成功');
                c(function(res) {
                    if (res) {
                        console.log('c执行成功');
                    } else {
                        console.log('c执行失败,结束');
                    }
                });
            } else {
                console.log('b执行失败,结束');
            }
        });
    } else {
        console.log('a执行失败,结束');
    }
});

function a(callback) {
  callback(true);
}

function b(callback) {
  callback(true);
}

function c(callback) {
  callback(true);
}
Read more »

一、常见数据类型

JavaScript中可以用typeof获取某个变量的数据类型,常见的数据类型有:number,string,boolean,object,function,undefined,直接看代码:

let a = 1;
let b = 1.222;
alert(typeof(a)); // number
alert(typeof(b)); // number

let c = '1';
let d = 'hello';
let k = '';
alert(typeof(c)); // string
alert(typeof(d)); // string
alert(typeof(k)); // string

let e = true;
alert(typeof(e)); // boolean

let m = window;
let n = {};
let p = null;
let q = [1, 2, 3];
alert(typeof(m)); // object
alert(typeof(n)); // object
alert(typeof(p)); // object
alert(typeof(q)); // object

let fun = function() {}
alert(typeof(fun)); // function

let json = {}
alert(json.a); // undefined
let y;
alert(y); // undefined
let fun1 = function(){
    return;
}
alert(fun1()); // undefined
let fun2 = function(){}
alert(fun2()); // undefined
Read more »

变量、常量、数组

定义变量使用var,定义常量使用val,Kotlin会根据值自动推断类型,不需要自行指定,如下:

var a = 1
val b = 2

当然你要指定也可以:

var a: Int = 1

定义可空变量和常量:

var android: String? = null
val name: String? = null
Read more »

一、前言

EventBus是一个开源的事件总线框架,Android中被广泛使用,目前最新的版本为3.2.0,github地址:https://github.com/greenrobot/EventBus

二、简单使用

  1. 在build.gradle中引入依赖:

    implementation 'org.greenrobot:eventbus:3.2.0'
  2. 定义事件实体类:

    public class CallEvent {
    }
  3. 订阅消息:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
    
    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onEvent(CallEvent event) {
        // TODO 
    }
  4. 发送消息:

    CallEvent event = new CallEvent();
    EventBus.getDefault().post(event);
  5. 来到这里就可以把EventBus用起来了,不过这里有个问题,注册时会反射遍历注册类的所有被Subscribe注解的方法,这个过程比较耗时会影响性能,因此EventBus又提供了一个eventbus-annotation-processor库来解决该问题,因此我们把它引入进来:

    annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.0.1'
  6. 这个eventbus-annotation-processor还需要一个key为eventBusIndex的键值对,用来指明自动生成的类的类名:

    android {
        defaultConfig {
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [ eventBusIndex : 'org.greenrobot.eventbusperf.MyEventBusIndex' ]
                }
            }
        }
  7. 然后编译代码,就可以在build/source/apt/debug/下看到自动生成了org.greenrobot.eventbusperf.MyEventBusIndex类,这时我们需要把这个类添加到EventBus中:

    EventBus.builder()
        .addIndex(new MyEventBusIndex())
        .installDefaultEventBus();
  8. 配置到此结束,可以愉快地使用了。

Read more »

题意

As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:

Correct parentheses sequences can be defined recursively as follows:
1.The empty string “” is a correct sequence.
2.If “X” and “Y” are correct sequences, then “XY” (the concatenation of X and Y) is a correct sequence.
3.If “X” is a correct sequence, then “(X)” is a correct sequence.
Each correct parentheses sequence can be derived using the above rules.
Examples of correct parentheses sequences include “”, “()”, “()()()”, “(()())”, and “(((())))”.

Now Yuta has a parentheses sequence S, and he wants Rikka to choose two different position i,j and swap Si,Sj.

Rikka likes correct parentheses sequence. So she wants to know if she can change S to a correct parentheses sequence after this operation.

It is too difficult for Rikka. Can you help her?

Read more »