好久没更新博客了,今天抽空写点东西。最近一篇博客,讲的是怎么拷贝代码,那为什么会有这样一篇文章呢?
嘿嘿,2018 年 2 月 9 号,我离职了。
在公司呆了有段时间了,觉得公司技术其实是很不错的,可惜发展不太好。前期融资的钱烧得差不多了,却仍然没有创造合理的商业模式进行营利,导致公司很难运营下去,也很难继续拉到投资。公司开始拖欠工资,后面很多员工都陆续离职了。我呢,想着可能还有点机会,一直继续干。但是坚持到年底仍然没什么起色,心灰意冷,就只能离职了。
那是一座悲欢离合聚集的楼。
作为程序员,我们总会有各种拷贝代码的需求,例如现场部署,基友探讨,亦或是 公司电脑 -> 自家电脑 等等。最最无脑的就是直接硬盘拷贝了,复制代码文件夹或压缩文件,直接拷贝到自己的硬盘或 U 盘里。但是作为安卓开发,如果要拷贝安卓代码,那就很费劲了。因为 Android Studio 会生成各种与代码无关的文件,尤其是 build 文件夹,有些时候代码可能就一两百兆,但是 build 文件夹就能有大几百兆甚至上 G 了。当然我们可以先 clean,然后再拷贝,但是如果项目复杂,多个工程多个 Module 互相依赖的,那就得每个 Module 都执行一遍 clean 了,想想那有多繁杂。
现在大多的代码版本控制都是采用的 Git,我们需要的其实就只是代码文件,其他的一概不需要,而 Git 内部的 .gitignore 不是正好对应我们的需求吗?所以,我们得从版本控制的角度来拷贝代码。相信大多数公司项目的代码都是私有仓库,只能在公司内网访问到。但我们可以给代码添加远程仓库 origin,这个 origin 可以指到 Github 或自己搭建的 Git 服务器,但是如果是公司代码是不建议这么做的,泄密了嘛~若是自己写的小工具,三方库倒是没什么影响,但这也不是本文要说的重点。
今天就说一下利用 Git 拷贝代码的新姿势,SVN 或其他版本控制工具不在此文范围之内。其实就是一个 Git 命令:git bundle。
more >>相信现在越来越多的开发者都在使用 RxJava 和 Kotlin,当二者相遇,写出来的代码堪称优雅!
我对 Kotlin 的并没有很特别的感觉,它就类似于 Swift 相比于 OC,大量的语法糖着实能使写代码的效率变高,但是是否能左右 Android 开发的现状还未可知。
我之前写过这样一段话,在使用 Kotlin 的这段时间里,我对它的看法慢慢改变了。尤其引入 RxJava 后,结合 Lambda 表达式,写起代码简直像要飞起来!
more >>项目开发中,我们的 App 这个 Module 定义了3个 buildType:1
2
3
4
5
6
7
8
9
10
11buildTypes {
release {
buildConfigField("Integer", "HOST_TYPE", '0')
}
debug {
buildConfigField("Integer", "HOST_TYPE", '1')
}
beta {
buildConfigField("Integer", "HOST_TYPE", '2')
}
}
通过参数 HOST_TYPE 来指定数据的环境。debug 为内网测试版,beta 为外网测试版,release 为正式版本。
项目有3个产品线:手机、POS机、收银机,Module 的依赖是这样的:
App 作为 Application,其他作为 Library。
之前有一个关于 MVP 的疑惑:1个 Presenter 能否对应多个 View?,在我的这篇文章中有写过。现在回过头来仔细想想,感觉有点不对劲:1个 Presenter 为什么会有对应多个 View 的需求呢?那篇文章中的使用场景是:
我有 A B C 三个页面,我有一个 Presenter,用来处理一个数据类型的增删改查,但是界面上,A界面只需要查询,B界面只需要删除,C界面只需要增和改。
我们都知道,Presenter 是用来抽离 Activity 或 Fragment 中的业务代码的,何为业务代码?就是这个页面涉及到的业务逻辑。关于数据的增删改查,那是 M 应该做的事,而绝不是 Presenter 该去处理的。 所以,Presenter 应当只对应一个 View,如果有界面复用 Presenter 的情况,那我们得考虑为什么会有这种情况呢?复用 Presenter 代表着业务逻辑是一致的,不同的页面理当有着不同的业务逻辑。当然,这里说的业务是简单,最小颗粒化的业务,如果一个页面十分复杂,Presenter 中集合了大量业务代码,那么在某些小的页面是有可能复用 Presenter 中的部分业务代码的。所以这种情况下,Presenter 会对应多个 View,那么这个场景使用上篇文章中的做法是可以的:复用 Presenter,将 View 抽离,利用继承实现多个界面的定制需求,但不会是上篇文章中的那种使用场景。
more >>写过几个星期的 Kotlin 代码了,再也不用 findViewById 了,使用起来稍微简洁一点。今天小结一下,基础用法就不多说了,直接写几点我感触较深的。
当使用Java开发的时候,我们的代码大多是防御性的。如果我们不想遇到 NullPointerException,我们就需要在使用它之前不停地去判断它是否为 null。Kotlin,则是空安全的,我们可以通过一个安全调用操作符 (写做 ? )来明确地指定一个对象是否能为空。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// 这里不能通过编译. Artist 不能是 null
var notNullArtist: Artist = null
// Artist 可以是 null
var artist: Artist? = null
// 无法编译, artist可能是 null,我们需要进行处理
artist.print()
// 只要在artist != null时才会打印
artist?.print()
// 智能转换. 如果我们在之前进行了空检查,则不需要使用安全调用操作符调用
if (artist != null) {
artist.print()
}
// 只有在确保 artist 不是 null 的情况下才能这么调用,否则它会抛出异常
artist!!.print()
// 使用 Elvis操作符 来给定一个在是 null 的情况下的替代值
val name = artist?.name ?: "empty"
关于 Elvis操作符 其实是三目条件运算符的简略写法。可以这样理解:
最近写过一个界面,涉及到排序。
用到了 Collections 中的 sort 方法:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15Collections.sort(mData, new Comparator<BookMemberReport>() {
@Override
public int compare(BookMemberReport lhs, BookMemberReport rhs) {
if (sortFlag == SORT_FLAG_SALE_DESCENDING) {
return (int) (rhs.saleAmount - lhs.saleAmount);
} else if (sortFlag == SORT_FLAG_SALE_ASCENDING) {
return (int) (lhs.saleAmount - rhs.saleAmount);
} else if (sortFlag == SORT_FLAG_COUNT_DESCENDING) {
return rhs.orderCount - lhs.orderCount;
} else if (sortFlag == SORT_FLAG_COUNT_ASCENDING) {
return lhs.orderCount - rhs.orderCount;
}
return 0;
}
});
Collections 根据传入的 Comparator 进行排序。刚开始写的时候通过不停的试,把正确的结果给试出来了。但是对于其原理却不是很清晰,今天便稍微扒一扒其源码。
more >>项目开发,引进了一个新的三方库,导致之前能运行的代码出现问题,错误堆栈:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19FATAL EXCEPTION: main
Process: com.lijia.app.catering.dev, PID: 29387
java.lang.NoClassDefFoundError: android.support.v4.animation.AnimatorCompatHelper
at android.support.v7.widget.DefaultItemAnimator.resetAnimation(DefaultItemAnimator.java:514)
at android.support.v7.widget.DefaultItemAnimator.animateAdd(DefaultItemAnimator.java:217)
at android.support.v7.widget.SimpleItemAnimator.animateAppearance(SimpleItemAnimator.java:114)
at android.support.v7.widget.RecyclerView.animateAppearance(RecyclerView.java:3243)
at android.support.v7.widget.RecyclerView.access$800(RecyclerView.java:147)
at android.support.v7.widget.RecyclerView$4.processAppeared(RecyclerView.java:436)
at android.support.v7.widget.ViewInfoStore.process(ViewInfoStore.java:249)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep3(RecyclerView.java:3098)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2917)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3283)
at android.view.View.layout(View.java)
at android.view.ViewGroup.layout(ViewGroup.java)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java)
at android.widget.LinearLayout.onLayout(LinearLayout.java)
...
最近随着 Google 的大力推荐,越来越多开发者开始使用 Kotlin 了。其实我对 Kotlin 的并没有很特别的感觉,它就类似于 Swift 相比于 OC,大量的语法糖着实能使写代码的效率变高,但是是否能左右 Android 开发的现状还未可知。我接触 Kotlin 的主要原因是:业务代码太无聊啦。相信很多开发者都跟我有同样的感触,在一个公司待久了,技术框架摸透之后,后面的开发就基本是纯业务开发了,写界面,写业务代码,对于技术提升没有什么实质的帮助,就是真正的码农。为了改变这一现状,我不断在新需求中使用一些新的技术,比如 RxJava、Retrofit 等等,说是新技术其实也不新了,都出来都很久了,只是自己在项目中没有用到,接触得不多。在新需求中引入这些技术,可以边开发边学习,解决写业务代码的无聊,还能拓宽视野,学习新知识。虽然不一定会成为主流,但学习一下总是没问题的,因此开始接触 Kotlin。这篇文章主要先讲讲 Kotlin 的配置。
最新的 Android Studio 已默认装了 Kotlin 插件了,在旧版本可自己手动安装 Kotlin 插件。
more >>tag:
缺失模块。
1、在博客根目录(注意不是yilia根目录)执行以下命令:
npm i hexo-generator-json-content --save
2、在根目录_config.yml里添加配置:
jsonContent: meta: false pages: false posts: title: true date: true path: true text: true raw: false content: false slug: false updated: false comments: false link: false permalink: false excerpt: false categories: false tags: true