Gradle

1
classpath 'com.android.tools.build:gradle:3.0.0'

官方默认搭配是 gradle 4.1,如果换成 4.2.1 正式版,速度将更快:

1
distributionUrl=https\://services.gradle.org/distributions/gradle-4.2.1-all.zip

因为 gradle 下载很慢,你可以选择百度网盘下载(我上传的,可以放心):

gradle-4.2.1-all.zip http://pan.baidu.com/s/1mi22zMg

新的编译方式

原先的 compile 关键词现在变成了 api,但一般情况下不应该使用 api,因为 api 是会向外暴露你引用的依赖,这样会导致 gradle 编译时需要频繁遍历所有嵌套依赖是否有变更,影响编译速度。更推荐的是使用 implementation 替代原先的 compileimplementationapi 的区别就是不会暴露引用的依赖。比如 A implementation 引用了 B,如果 B implementation 引用了 C,那么 A 将无法间接引用 C,除非 A 自己也声明引用 C。而如果 A implementation B,B api C,则 A 可以间接引用 C。

使用 implementation 是提升编译速度的关键。如果没有必要引用间接内容的话,应该尽量使用 implementation

关于此有一篇写得比官方清楚很多的好文章:

https://stackoverflow.com/questions/44413952/gradle-implementation-vs-api-configuration

另外,原先的 provided 现在改名为 compileOnly,并新增了 runtimeOnly

设置编译生成应用文件名称

Gradle 3.0 更改了设置编译生成应用文件名称的方式,新的方式和原先相比略为不同,但更简单直观:

示例:

1
2
3
4
5
6
7
8
9
applicationVariants.all { variant ->
variant.outputs.all {
def apkName = 'AppName' + '-' + variant.versionName
if (!variant.flavorName.isEmpty()) {
apkName += ('-' + variant.flavorName)
}
outputFileName = apkName + '.apk'
}
}

启用 Java 8 支持

Gradle 带来了新的 Java 8 兼容方案 desugar,启用方式十分简单,只要在 gradle android 层次之下加入如下代码即可:

1
2
3
4
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

目前 desugar 兼容支持的内容有:

  • Lambda expressions
  • Method References
  • Type Annotations
  • Default and static interface methods
  • Repeating annotations

不支持 stream、function

禁用 desugar:

1
android.enableDesugar=false

更多详情:https://developer.android.com/studio/write/java8-support.html

配置构建变体

flavor 配置有变,官方中文文档,很详细,见文档就是了:

https://developer.android.com/studio/build/build-variants.html?hl=zh-cn

AAPT2

AAPT2 将默认启用,如果遇到离奇的问题,可以尝试禁用,只要在 gradle.properties 中加入:

1
android.enableAapt2=false

Support Library 26.1.0

  • Fragment and FragmentActivity (the base class for AppCompatActivity) now implement the LifecycleOwner interface from Architecture Components.

  • All instances of the findViewById() method now return T instead of View. This change has the following implications

  • FragmentManager and Fragment have an isStateSaved() method to allow querying whether or not a transaction will be allowed without state loss. This is especially useful to check when handling an onClick() event before executing any transaction.

  • Path motion is supported in AnimatedVectorDrawableCompat. Path motion allows one object animator to change two properties at the same time based on one path; the path is specified as android:pathData in the animator’s XML).

  • New FlingAnimation that supports animating with an initial velocity and smoothly slows down.、

  • Support libs v26 版本完美解决了 AppBarLayout$ScrollingViewBehavior fling 的问题,介绍和演示相关微博:http://weibo.com/2263023493/FkQscgdRt?from=page_1005052263023493_profile

  • ResourcesCompat.getFont allows loading font resources—including font-family XML—that may be used with TextView.setTypeface().

  • Downloadable fonts

  • Emoji compatibility library(19+)

  • Autosizing TextView

  • PreferenceDataStore now allows you to implement your own preferences storage, set with new methods in Preference and PreferenceManager.

其他

  • 对 ConstraintLayout 编辑更好的支持,之前 ConstraintLayout XML 内容容易遇到一些属性值被破坏的情况,3.0 不再发生。

Lifecycle Arch

示例(相关微博:http://weibo.com/2263023493/Fmvia7Jqs?from=page_1005052263023493_profile ):

/**
 * @author drakeet
 */
public class UpdateDelegate implements LifecycleObserver, Callback {

    private @NonNull final XxxActivity activity;
    private Call call;


    private UpdateDelegate(@NonNull XxxActivity activity) {
        this.activity = activity;
    }


    public static <Owner extends XxxActivity & LifecycleOwner> void attach(@NonNull Owner owner) {
        UpdateDelegate delegate = new UpdateDelegate(owner);
        owner.getLifecycle().addObserver(delegate);
    }


    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void onStart() {
        call = Api.create().checkUpdate(this);
    }


    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void onStop() {
        if (call != null) {
            call.cancel();
        }
    }


    @Override
    public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
        try {
            ...
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }


    @Override
    public void onFailure(@NonNull Call call, @NonNull IOException e) {}
}

支持与感谢

如果你因为我的文章而受益,你需要对此文进行付费,这样我花费的时间可以得到一些回报,就像王垠说的:

我一直很高尚的样子,不愿意为此收费。然而,根据经济学的原理,这是有害社会的 :P 经济的原理是这样,有价值的事物,应该在经济上受到相应的支持,这样好的东西才能受到鼓励,发扬光大,不好的东西才可能被人忘记。

所以现在我决定,给我觉得价值比较大的文章加上大概的价格,这样喜欢文章的人可以自愿付费,当然也可以不付费。谢谢你的支持!
等价交换,本文大概值 3 元人民币,你可以扫描以下支付宝对我进行付费打赏,谢谢:

非常感谢!

支付宝:drakeet@qq.com

或者,你也可以下载我最新开发的个人应用 纯纯写作 - 绝不丢失文本编辑器 App 进行应用内购买 Pro 内容付费对我进行支持,同样感谢!


除此之外,你还可以关注我的 telegram 频道获得更多实时分享:

Drakeet 的 telegram 广播频道,专用于分享一些技术上的看法、体验心得、一些库 / 项目的更新状况及解读(比如 AS、support lib),有时也会分享一些好玩的事物和文章链接:

https://t.me/drakeets