0%

前言

背景

大多时候,开发人员仅需使用少量的分支,甚至只需 master 和 develop 两个分支即可完成日常工作。这足以应付小型项目或小规模团队的开发工作,但随着协作人员的增多和项目周期的延长,各样的挑战便会纷至沓来…

阅读全文 »

Gradle 插件简介

Gradle 插件是一个能够将 Gradle 的构建逻辑(build logic)和构建任务(build task)打包到一起,以便在多个项目的构建脚本(build.gradle)中应用(apply)的工具。

例如,build.gradle 构建脚本文件内 apply plugin: 'java'apply plugin: 'com.android.application' 中的 javacom.android.application 就是官方提供的 Gradle 插件,通过应用这些插件,可以丰富项目的构建任务与构建逻辑。

阅读全文 »

Kotlin-Everywhere

在今年五月份的 Google I/O 大会上,Google 宣布了 Android 应用开发中 Kotlin 优先的战略,此后 Google 提供的 API(例如 Jetpack 工具库)将以 Kotlin 优先。大会结束后不久,Google 便联合 Jetbrains 在全球范围内推出了 Koltin/Everywhere 计划。Kotlin/Everywhere 计划 是由各地社区主导的一系列活动,旨在关注 Kotlin 在多平台上的潜力,并为学习 Kotlin 的基本要素与最佳实践提供帮助,包括但不限于 Android、服务端、前端和其他平台。

阅读全文 »

MultiType 是一个为 RecycleView 创建多种 Item 的 Android 库,它的设计简洁优雅,源码阅读体验也很好,本文记录了笔者研读此项目源码的感悟。

MultiType 的简单使用

开始之前,先来看下 MultiType 的总体类图

阅读全文 »

随着移动端设备增量的放缓和市场上各行各业 App 的饱和,连笔者的手机都很久未安装过新 App,更不用提更换手机的频率。与此同时,移动开发也由上半场拼点子拼速度的快捷玩法,进入到下半场拼质量拼生态的高阶玩法。作为一名一线开发人员,大环境的走向与业务形态的发展虽由不得我们控制,但核心技术的掌握则是我们可以身体力行的( 笑~)。

AOSP 是 Android 系统的代码,囊括了 Andorid 系统的全部内容,从应用开发 Framework 层到 Android 虚拟机 ART/Dalvik 层再到 Linux 内核层,所有的疑惑都能在源码中找到答案,其源码的重要性不言而喻。本文作为系列的开篇,主要对 AOSP 的下载、编译过程进行阐述,同时记录下过程中遇到的问题及解决方案。

笔者的系统版本为 macOS 10.14.5,截止文章发布时仍是最新的操作系统,AOSP-android-9.0.0_r42 的源码加编译产物需要 200G 的磁盘空间,请提前预留好磁盘空间。若主机磁盘空间不足,可使用外置移动硬盘来解决。

阅读全文 »

前不久,七牛收回了其测试域名,导致先前创建的外链失效,关联的图片也因此而无法加载。继续使用七牛云的话,需要绑定一个已备案的域名。我没有域名,只能选择将七牛中的数据迁出,本文记录了我的迁出方案,仅供参考。

七牛控制台

登录七牛控制台,看到之前上传的文件都还在,不由松了一口气。

阅读全文 »

Android开发中,有时需要同时finish多个Activity,避免用户点击后退按钮时回退到不该呈现的Activity。对于这样的问题,常见的方式是维护一个单例ActivityList,将多个Activity置入此单例列表,需要关闭多个Activity时可遍历该List依次执行finish操作。
代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class ActivityUtil {
private static List<Activity> activityList;
private static ActivityUtil instance;
private ActivityUtil() {
}
public static ActivityUtil getInstance() {
return null == instance ? new ActivityUtil() : instance;
}
public List<Activity> getActivityList() {
return activityList;
}
//向栈中添加Activity
public void addActivity(Activity activity) {
if (activityList == null) {
activityList = new ArrayList<>();
}
activityList.add(activity);
}
//关闭栈中指定的Activity
public void removeActivity(Activity activity) {
if (activity != null && activityList.contains(activity)) {
activityList.remove(activity);
}
}
//关闭栈顶的Activity
public void removeLastActivity(){
if (activityList.size()>1){
activityList.remove(activityList.size()-1);
}
}
//关闭栈顶topN个Activity
public void finishLastActivites(int n){
int p = activityList.size() - n;
if ( p >= 0 ) {
Iterator<Activity> iterator = activityList.iterator();
int i = 0;
while(iterator.hasNext()){
Activity activity = iterator.next();
if ( i++ >= p ) {
iterator.remove();
if (!activity.isFinishing()) {
activity.finish();
}
}
}
}
}
//关闭栈中所有的Activity
public void finishAllActivity() {
if (null != activityList) {
for (Activity activity : activityList) {
if (!activity.isFinishing()) {
activity.finish();
}
}
activityList.clear();
}
}
}

这样的代码本身没有问题,但开发时非常容易忘掉此处List中的引用而直接在外部finish,从而造成内存泄露。我们可以在List中使用WeakReference来避免这样的内存泄露。
代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class ActivityUtil {
private static List<WeakReference<Activity>> activityList;
private static ActivityUtil instance;
private ActivityUtil() {}
public static ActivityUtil getInstance() {
return null == instance ? new ActivityUtil() : instance;
}
public List<WeakReference<Activity>> getActivityList() {
return activityList;
}
public void addActivity(Activity activity) {
if (activityList == null) {
activityList = new ArrayList<>();
}
//使用WeakReference持有Activity
WeakReference<Activity> weakReference = new WeakReference<>(activity);
activityList.add(weakReference);
}
public void removeActivity(Activity activity) {
for (WeakReference<Activity> weakReference : activityList) {
if (weakReference.get() == activity) {
activityList.remove(weakReference);
break;
}
}
}
public void removeLastActivity() {
if (activityList.size() > 1) {
activityList.remove(activityList.size() - 1);
}
}
public void finishLastActivites(int n) {
int p = activityList.size() - n;
if (p >= 0) {
Iterator<WeakReference<Activity>> iterator = activityList.iterator();
int i = 0;
while (iterator.hasNext()) {
Activity activity = iterator.next().get();
if (i++ >= p) {
iterator.remove();
if (!activity.isFinishing()) {
activity.finish();
}
}
}
}
}
public void finishAllActivity() {
if (null != activityList) {
for (WeakReference<Activity> weakReference : activityList) {
if (!weakReference.get().isFinishing()) {
weakReference.get().finish();
}
}
activityList.clear();
}
}

}

阅读全文 »

前言

Android Architecture Blueprints 是谷歌官方开源的一组 Android 架构方案,项目以多个分支分别采用 MVPMVVM 的概念以及 dagger、rxjava、databinding、livedata 等工具库,演示了一个简单的 TodoApp 在不同架构模式下的代码组织方式。这个项目中的代码非常规范,架构模式也非常有借鉴意义,是一个很有价值的学习素材。

本文将通过 项目组织架构组织与通信设计原则 这三个层次对项目中的todo-mvp分支进行解析,从而达到学习的目的。

阅读全文 »