Kotlin学习笔记(二):变量与函数

之前文章起名为Kotlin教程,后来想想可能不大合适,决定改为Kotlin学习笔记。上一篇文章发布后,有几个读者留言问在没有学Java的情况下,直接学Kotlin行不行?我认为是没有问题的。好了,上一篇文章已经简单了解Kotlin的一些特色,后面也用Kotlin写了一个最简单的HelloWorld,如果还不大清楚的朋友,可以先阅读上一篇文章:Kotlin学习笔记(一):走进Kotlin的世界

包名

Kotlin在包名声明和类型导入上和Java基本一样,风格如下:

1
2
3
4
package xxx.xxx.xxx //包名声明
import xxx.xxx.xxx //类型导入
...

和每个Java文件都会默认导入import java.lang.* 一样,Kotlin也会默认导入如下的包,并且根据运行在不同平台上,默认导入的包会有些许差异。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 每个Kotlin文件会默认导入下面的包
kotlin.*
kotlin.annotation.*
kotlin.collections.*
kotlin.comparisons.*
kotlin.io.*
kotlin.ranges.*
kotlin.sequences.*
kotlin.text.*
// JVM下的Kotlin还会导入
java.lang.*
kotlin.jvm.*
// JS下的Kotlin还会导入
kotlin.js.*

数值类型

Kotlin的数值类型包括Byte(1个字节)、Short(2个字节)、Int(4个字节)、Long(8个字节)、Float(4个字节)、Double(8个字节)。

继续阅读全文 »

Kotlin学习笔记(一):走进Kotlin的世界

今年Google I/O大会上,官方扶正Kotlin的举动火遍整个Android开发圈。不过,有些开发者似乎过度解读Google的意图,认为Kotlin要取代Java成为Android开发的标配,大会上说的是official support kotlin,并非replace java with kotlin。以至于后来回公司上班,后台童鞋打招呼的时候还问,听说你们Android以后不用Java要用Kotlin写(那位后台童鞋之前用Kotlin写过服务器代码)。好吧,我本人是不支持官方一支持Kotlin后,就说Java辣鸡,Kotlin才是王道这类说法。毕竟,语言终究有自己的优缺点,既然官方开始支持了,我们不妨利用一些空余时间学习一下Kotlin好了。

Kotlin简介

Kotlin是JetBrains推出项目,是一种在Java虚拟机上运行的静态类型编程语言,也可以被编译成为JavaScript源代码。在2011年7月推出之前,它已被开发一年之久。直到2016年2月15日,官方发布了第一个稳定的release版本 —— Kotlin v1.0。从Kotlin官网介绍来看,这近乎是一门野心勃勃的语言,

  • 基于JVM编程,这意味着Kotlin可以写服务器代码;
  • 基于Android和Browser编程,这意味着不仅可以写客户端编程,连前端开发都可以;
  • 基于Native编程,直接绕过JVM与底层代码打交道,好彪悍;

不过Kotlin-Native项目还在开发阶段,不知道最终推出的项目如何,还是蛮期待的,感兴趣的朋友可以关注它的Github更新

https://github.com/JetBrains/kotlin-native

继续阅读全文 »

Android卡顿检测方案

应用的流畅度最直接的影响了App的用户体验,轻微的卡顿有时导致用户的界面操作需要等待一两秒钟才能生效,严重的卡顿则导致系统直接弹出ANR的提示窗口,让用户选择要继续等待还是关闭应用。

所以,如果想要提升用户体验,就需要尽量避免卡顿的产生,否则用户经历几次类似场景之后,只会动动手指卸载应用,再顺手到应用商店给个差评。关于卡顿的分析方案,已经有以下两种:

  • 分析trace文件。通过分析系统的/data/anr/traces.txt,来找到导致UI线程阻塞的源头,这种方案比较适合开发过程中使用,而不适合线上环境;
  • 使用BlockCanary开源方案。其原理是利用Looper中的loop输出的>>>>> Dispatching to和<<<<< Finished to这样的log,这种方案适合开发过程和上线的时候使用,但也有个弊端,就是如果系统移除了前面两个log,检测可能会面临失效;

下面就开始说本文要提及的卡顿检测实现方案,原理简单,代码量也不多,只有BlockLooper和BlockError两个类。

继续阅读全文 »

开源整理:Android App新手指引开源控件

一个App第一次与用户接触或者发生大版本更新时,常常会用户进行新手引导,而一个好的新手指引,往往能够方便新用户快速了解操作你的应用功能。新手指引的重要性,不言而喻。本文搜集整理了Github上一些效果不错的新手指引开源控件,帮助你的应用在用户面前有更好的效果展示。当然,如果你有精力,也可以自己开发维护一套新手指引效果。

GuideView

https://github.com/binIoter/GuideView

国人开发者出品的一个轻量级新手指引库,能够快速为任何一个View创建一个遮罩层,支持单个页面,多个引导提示,支持为高亮区域设置不同的图形,支持引导动画,方便扩展,良好支持fragment。

使用方式、更多效果、详细实现原理等,可以查看项目的README。

Spotlight

https://github.com/wooplr/Spotlight

看看下面的效果后相比静态的指引效果,这种动态指引更容易让用户耳目一新,可以在新功能的入口处添加提示。

MaterialIntroView

继续阅读全文 »

使用Git部署Hexo博客到Ubuntu服务器

本站服务器由UCloud( https://www.ucloud.cn/ )公司赞助提供!

Hexo是使用Node.js开发的静态站点生成器,支持Markdown语法写作,并且有着强大的插件系统,是不少技术开发者搭建个人博客的一个好选择,本文将介绍如何在一台Ubuntu云服务器上使用Git部署Hexo博客站点。

前提条件

  1. 安装Ubuntu操作系统的云服务器一台,同时还需安装Nginx和Git,分别用于静态页面托管以及版本管理部署等;
  2. 本地电脑安装node.js环境以及npm;
  3. 本地电脑安装Git环境;
  4. 本地电脑安装SSH终端;(非必要条件,但是安装了可以方便你访问云服务器,我用的是Xshell,也可以考虑用PuTTY、SecureCRT等)

了解完以上前提条件后,开始动手搭建自己的博客吧。

Nginx配置

购买一台云服务器,由于初期流量不是很大,服务器可以不需要很高的配置,等到需要时再升级(云服务器升级配置很方便的)。下面是我的服务器配置,我在服务器上安装了Ubuntu 16.04版本的操作系统。

登录远程服务器(使用SSH终端远程登录操作更方便),安装Nginx

1
sudo apt-get install nginx

安装完成后(这时我们还没有配置域名),在浏览器直接通过IP地址可以看到下面的网页提示,可以看到下面的网页提示说明安装成功。

接下来,创建/home/ubuntu/www/hexo_blog目录用于Nginx托管网页

1
2
cd /home/ubuntu
sudo mkdir -p www/hexo_blog

使用vim修改Nginx的默认配置文件

1
sudo vim /etc/nginx/sites-available/default

将其中的root指向我们上一步创建的/home/ubuntu/www/hexo_blog目录,同时配置你购买的域名到server_name

1
2
3
4
5
6
7
8
9
10
11
12
...
server {
...
...
root /home/ubuntu/www/hexo_blog; # 指向你的托管目录
index index.html index.htm;
...
...
server_name blog.coderclock.com; # 设置你的域名
...

最后重启你的Nginx服务器,让配置生效。

1
sudo service nginx restart

完成Nginx配置后,接下来是Git配置。

继续阅读全文 »

Android SO文件的兼容和适配

开发Android应用时,有时候Java层的编码不能满足实现需求,就需要到C/C++实现后生成SO文件,再用System.loadLibrary()加载进行调用,这里成为JNI层的实现。常见的场景如:加解密算法,音视频编解码等。在生成SO文件时,需要考虑适配市面上不同手机CPU架构,而生成支持不同平台的SO文件进行兼容。目前Android共支持七种不同类型的CPU架构,分别是:ARMv5,ARMv7 (从2010年起),x86 (从2011年起),MIPS (从2012年起),ARMv8,MIPS64和x86_64 (从2014年起)。如果你要完美兼容所有类型的手机,理论上是要在的libs目录下放置各个架构平台的SO文件。

这样一来,虽然可以兼容所有机型,但你的项目体积也会变得非常庞大。是否一定需要带入这么多SO文件去兼容呢?答案是否定的。

继续阅读全文 »

为什么ContentResolver调用bulkInsert批量插入数据失败

做Android开发的朋友肯定对使用ContentProvider插入数据并不陌生,通常我们使用ContentProvider基本都是经历如下两个步骤:

  • 声明定义ContentProvider及其相关的URI,编写Provider中对应的增删改查方法;
  • 使用ContentResolver及其对应的URI来对ContentProvider进行增删改查操作;

对于使用ContentProvider进行插入操作,分别可以使用insert、bulkInsert两个API接口,前者用于单条数据插入操作,后者则更适合批量数据插入操作,简单的了解了一遍ContentProvider的相关知识后,来看看下面这段代码:

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
public static void addOrUpdateContacts(Context context, Collection<ContactStruct> contacts) {
if (contacts == null || contacts.isEmpty()) {
return;
}
final int kCount = contacts.size();
ContentValues[] valuesArray = new ContentValues[kCount];
int pos = 0;
for (ContactStruct contact : contacts) {
ContentValues values = new ContentValues();
values.put(ContactTable.COLUMN_UID, contact.uid);
values.put(ContactTable.COLUMN_NAME, contact.name);
values.put(ContactTable.COLUMN_PHONE, contact.phone);
values.put(ContactTable.COLUMN_PINYIN, contact.pinyin);
values.put(ContactTable.COLUMN_REMARK, contact.remark);
// add "REPLACE" flag
values.put(ContactProvider.SQL_INSERT_OR_REPLACE, true);
valuesArray[pos++] = values;
}
try {
int ret = context.getContentResolver().bulkInsert(ContactProvider.Contact.CONTENT_URI, valuesArray);
if (ret != kCount) {
Log.e(Log.TAG_DATABASE, "addOrUpdateContacts partial failed, succ:" + ret + ",total:" + kCount);
}
} catch (Exception e) {
e.printStackTrace();
}
}

其传入contacts是一组联系人信息数据,通过一个循环的转换成ContentValues类型的数组,再使用context.getContentResolver().bulkInsert将ContentValues数组插入到数据库中去。简单的了解这段代码的作用后,大家觉得这种写法是否存在问题呢?

继续阅读全文 »

开源推荐:Android图片压缩开源库

推荐两个Github上开源的Android图片压缩库,两个库的代码量不多,可以直接使用或者借鉴学习。商业使用,别忘了遵循其对应的开源协议

需求场景

图片压缩在Android开发的需求中非常常见,如:拍照上传服务器,选择原图上传或者压缩上传,这里必然会涉及到压缩处理图片的问题。

Luban

https://github.com/Curzibn/Luban

Luban,也称鲁班。该库作者一针见血的提出当前图片压缩处理的一些问题:单纯对图片进行裁切,压缩已经有很多文章介绍。但是裁切成多少,压缩成多少却很难控制好,裁切过头图片太小,质量压缩过头则显示效果太差。所以,他通过微信朋友圈发送近100张不同分辨率图片,对比原图与微信压缩后的图片逆向推算出来的压缩算法,具体的算法实现在项目中有详细说明介绍。使用上,支持普通调用方式外,也支持RxJava!

Compressor

继续阅读全文 »

Android ConstraintLayout使用指南

升级Android Studio 2.3之后,IDE默认生成的Activity布局都是以ConstraintLayout做为根布局,体验了一把这个Google去年就开始力推的ConstraintLayout后,觉得非常不错,本文用于记录ConstraintLayout各个方面的使用知识。

平台支持

  • ConstraintLayout最低兼容Android 2.3;
  • 目前Android Studio 2.3默认使用ConstraintLayout作为布局文件的根布局;
  • 想要使用ConstraintLayout,需在项目的build.gradle添加com.android.support.constraint:constraint-layout:XXX版本号依赖;

基础使用

ConstraintLayout翻译成中文也称为约束布局,在整个使用体验过程中真的是贯穿约束二字,这一节先来介绍一些基础使用,后面你就会慢慢感受到约束布局的魅力。创建完工程后打开布局文件,底部切换Design的Tab上,可以看到整个操作界面

左上角的面板是放置了系统内置各种各样的控件,想要布局直接拖到到布局文件中即可(所见即所得),右边的面板是选中布局文件中的控件时期各种各样的空间属性,ConstraintLayout最大的好处在于让我们通过拖控件的形式进行布局,并且不用担心适配问题。所以,先来拖个控件试试看,将一个Button拖动到屏幕正中央,然后运行显示看看效果。

模拟器运行后的效果

而实际运行后却发现,这个Button还是位于屏幕左上角,说好的居中效果呢?这里就要开始引入ConstraintLayout的约束概念,我们切换回去看xml的布局代码,发现了两个问题。第一,布局预览时能够看到显示居中的Button,是因为控件属性设置中引用了两个tools命名空间下的属性。

继续阅读全文 »

利用Android源码,轻松实现汉字转拼音功能

今天和大家分享一个从Android系统源代码提取出来的汉字转成拼音实现方案,只要一个类,560多行代码就可以让你轻松实现汉字转成拼音的功能,且无需其他任何第三方依赖。

需求场景

实际开发过程中需要用到实现汉字转成拼音的场景比较常见,如:通讯录里的联系人字母导航栏,为没有设置头像的用户生成一个名字首字母的头像,国家(省份、城市)字母导航栏,搜索关键字转换成拼音等。

实现方案

Android平台上将汉字转换成为拼音已经有一些开源的第三方实现方案,如pinyin4j和TinyPinyin

pinyin4j:https://sourceforge.net/projects/pinyin4j
TinyPinyin:https://github.com/promeG/TinyPinyin

以上这两个实现方案,都需要引入不少类以及一些相应的编码文件,这里和大家介绍一个比上面两个方案还要精简的实现方案,只要560行代码且无需依赖于其他任何编文件的实现。这个类是从Android系统通讯录源码中提取的,类名为HanziToPinyin,其类文件路径如下:

/packages/providers/ContactsProvider/src/com/android/providers/contacts/HanziToPinyin.java

这是一个很独立的类,需要使用的项目直接拷贝到自己对应的工程里面即可使用,需要注意的是,我是在Android 4.2.2的系统源码中拷贝出来的,为什么选择4.2.2,一个是4.2.2之后(4.3开始)的HanziToPinyin不再可以独立使用,需要依赖于Transliterator,而这个类我们是无法直接引用的。

而Android 2.x的HanziToPinyin在测试了很多转换的结果发现是错误的,所以选择了最后一个可以采纳使用的版本Android 4.2.2。

继续阅读全文 »