从0开始学Android

有个小孩想学Android,没有Java背景,基本没编程经验。这是一个简单的2+2+2方案:

1.  2个学习网站

超经典的入门教程: https://code.google.com/p/androidbmi/wiki/DiveIntoAndroid
权威的教程(英文好一点其实这就足够了): http://developer.android.com/training/index.html

2. 2本参考书

Java2参考大全(第五版)(高清晰文字版)(Herbert.pdf)

Android应用开发入门教程(经典版).pdf

3. 2个论坛

 http://www.apkbus.com/
http://www.eoeandroid.com/

Java里byte和int对比问题

蓝牙或者串口读数据一般用byte数组,数据协议如果这样写 0xa5 0xaa, 新人往往会犯这样的错误:

(1)if(buffer[0] == 0xa5 && buffer[1] == 0xaa)…

(2)int value =  buffer[0] ;

结果却不尽人意,为什么呢?

有时候会这么改,

if((int)buffer[0] == 0xa5 && buffer[1] == 0xaa)…,怎么还不对呢?

其实应该这么改:

(1)if(buffer[0] == (byte)0xa5 && buffer[1] == (byte)0xaa)…

(2)int value = buffer[0] >0?buffer[0]:(buffer[0]+256);

为什么呢?

(1)对比的时候,0xa5实际上是int类型,它的值是165,超过了byte的范围;而buffer[0]在计算机中会做一个int转byte的计算,因为字节不同,就变成了负数-91了。

前面增加(int)就相当于(int)(-91),无济于事;

(2)协议里面往往是0~255,,而Java里面却是-127~127,所以负数往往都是错误啦!

 

 

AndroidStudio一些内存设置

AndroidStudio是越用越依赖了,再也无法回去用Eclipse了。

有时候AndroidStudio会抱一些内存错误,比如“outofmemory”,比如“unable create VM”啊,一般是内存设置太大或者太小了。

简单的配置如下:

1. 修改VM的大小:  安装目录下找到“studio64.exe.vmoptions”文件,然后将前面的值增大下,比如:

-Xms512m
-Xmx1500m

修改完后,打开AndroidStudio就可以看到右下角内存大啦;

2. 修改Setting -》compiler-》Android DX Compiler

这里面的大小平时可以降低,避免创建虚拟机失败。

理解Android的Service

Google做的东西,理解起来其实都是比较明了的,所以Androidservice机制在GoogleAPI中并没有写的很多,用中文的“服务”去理解还是相当的准确的,就是用来提供“后台、数据服务”的东东。

很狗血的问题“ServiceThread有什么区别”,其实根本就没有可比性。Service是一种实现机制,而Thread是实现Service某些功能的办法。Service是相对Activity来说的,应该没有人会问“ActivityThread有什么区别”吧。

什么时候会用到Service

1. 后台数据的采集、同步,需要常驻后台时;

2. 相对独立的功能模块,用于提供某种数据服务或者其他无界面的功能服务(比如声音),供Activity使用;

3. 需要执行“有保障”的事情时,相当Activity的Thread来说,Service的Thread会有保障的多!

Service需要了解哪些东西?

1. Local Service/ Remote Service

2. Foreground Service / Background Service

3. Start Service / Bind Service

推荐参考:Android 中的 Service 全面总结

Android的定时器

这篇主要是接上篇“多线程”,因为定时器只能用于多线程中。

Android实现定时器有这些方式:

1. 标准的Java类Timer+TimerTask+Handler; 而Android推荐使用ScheduledThreadPoolExecutor替代TimerTask,

API上写到:

When this thread is busy running a task, runnable tasks may be subject to delays.

This class does not offer guarantees about the real-time nature of task scheduling.

 

2. 简单化的Handler+Runnable,通过Handler.postDelayed实现;这个和Timer应该是相同的问题。

 

3. Thread+Handler方式,通过Thread.sleep来实现。

不推荐使用,因为这种方式最不靠谱,API文档上说:

The precision is not guaranteed – the Thread may sleep more or less than requested.

 

4. Alarm+Receiver方式,用于做长时间的timer。

Timer使用要注意,任何时候使用时都要考虑用户取消这个timer的实现;

Android多线程的理解

Android开发中,多线程用的非常普遍,比如异步加载、定时处理。常用的方式有Thread+Handler方式,Runnable+Handler方式,AsyncTask方式等。

Thread+Handler方式是最Java的模式,也是大部分GUI软件架构的处理方式。所有的对象其实都有一个Handler,处理消息的收发,底层OS(?)处理消息的队列,包括默认的线程和消息优先级处理。另外,Handler应该也是一个特殊的线程。在Android里面,所有的OnXXX都是回调函数,其实也是这种模式,Activity接收系统的消息,然后调用这些回调进行处理。(Android源码不得不看啊!)

对于开发者,只需要新建一个自己的Handler,然后将Handler引用给需要的Thread就行啦。因此用这种模式应该可以解决所有的多线程任务。

 

Runnable+Handler方式是上面模式的一个简化封装版,RunnableThread的简化版,只实现了run接口;这边的Handler一般也只是一个最基本的Handler,并不需要去写消息处理。通过Handler可以很容易实现延时处理任务、Cancel延时任务。

类似的还有Timer+TimerTask,RunOnUIThread等;

 

AsyncTask是最Android的模式,它是用Android模式来封装Thread+Handler模式。只要在UI线程新建一个它的子类,实现几个OnXXX回调方法,就可以实现多线程处理了。

 

从使用来说,我觉得基本原则应该是尽量使用AsynTask,毕竟是Android封装的,代码容易看懂;能用Runnable就不用Thread,简化代码;而对于复杂的、线程较多的、需要长时间运行或者在后台长保的得用Thread

更高级的,应该是使用线程池了。

RFID发卡/刷卡流程(For Android)

最近在实现Android系统的刷卡功能。

最简单的是磁卡,USB OTG插上就能用,它其实就类似一个键盘的输入,但是磁卡不方便,还容易消磁,安全性差;第二种是RFID卡(M1卡),优势明显,但是能支持Android的很少。

对于能配合Android的RFID刷卡器,目前商用的可能只有一款ACR122U(售价¥200~300),如果需要更廉价的方式,也可以考虑Android+Arduino+RFID模块(成本大概100)。
下面就以ACR122U为例简单介绍下系统集成过程:(首先到http://www.acs.com.hk/下载一份SDK)

阅读更多RFID发卡/刷卡流程(For Android)

Android&Arduino之无线身高仪

超声波身高仪目前已经非常普及了,但带无线(BT/WiFi/3G)功能的身高仪市面上还没看到。购之不得,只好自己“研发”了。下面是我的一个Arduino&Android实现方案,经过实际测试,稳定度和精准度能够达到工业标准,申请专利了哈

系统的集成其实非常简单啦,一个Arduino板子,一个无线模块,一个工业级的超声波模块,然后就是Android处理无线通信的代码啦。目前我实现的是蓝牙的接口,如果哪位有兴趣商用化该产品,可以联系我索要代码呢。

bt