与Linux系统相同,Android中每一个process也有一个自己的优先级,在PC系统中,进程或者线程的优先级决定了其获得运行资源的多少。而像iOS与Android系统中,优先级除了决定进程获得资源的多少之外,还决定了当系统处于资源紧张状态时,进程所能存活的时间。因为在Mobile操作系统中,都有OOM处理机制,即当系统资源紧张时,OS会根据一定的策略选择kill一掉一些进程,从而使系统拥有更多的资源可以运行下去,或者使优先级更高的进程能够有足够的资源运行。我们先从OOM机制说起。
实现类似Kitkat系统中的Time Picker
Android Kitkat自带的time picker很符合我的审美,看起来挺漂亮,使用起来也确实很方便。这个widget很简单,实现起来没有特别的难度,但是还是需要了解android绘制方面的某些细节才能够做到完美。我们先来看看time picker的样子:
this is test t new test
Time Picker的布局很简单,复杂点在中间表盘的绘制。在已知表盘中心和数字所在内圆的半径后,我们可以利用简单的三角函数的知识,计算每一个数字对应的位置,示意图如下:
Why AsyncTask is not suitable for long running operation
AsyncTask在Android的开发中是比较常用的一个类,AsyncTask提供的接口使我们能够很方便的将任务放到背景线程执行,并在任务执行的过程中及得到执行后,将结果回传给UI线程。但是Android中multiple thread 以及AsyncTask的使用却有许多值得注意的地方。
####AsyncTask不适合耗时较长的任务的原因####
虽然AsyncTask非常易用,但是在Android的开发文档中,明确表明了AsyncTasks should ideally be used for short operations (a few seconds at the most.)。为什么会有这么一条限制?通过阅读AsyncTask的源代码我们发现,AsyncTask的底层实现就是利用了Thread 和 Handler方式:
- 首先AsyncTask会在线程池中得到一个Thread,并将任务在Thread中执行
- 任务执行完毕后,Handler会将执行的结果返回给UI Thread的message loop,从而通知UI改变
这种执行方式并不应该限制任务的执行时间,因此AsyncTask不适用于长时间的工作的原因并不在与AsyncTask本身的实现机制。
下面我们看一下AsyncTask具有这个局限的根本原因。
在Activity中使用AsyncTask的基本流程如下:
- 在Activity中创建一个继承自AsyncTask的内部类,之所以采用内部类的实现,是为了方便的将结果返回给Activity时,我们能够很方便的得到Activity中定义的变量
- 在Activity中实例化一个AsyncTask变量,开始在背景线程执行工作。
这种工作流程实际上存在一些问题,主要如下:
Android中为自定义的View添加滚动效果
记得读到过一句话,大意为人为错误主要是由于工具的设计不合理导致的,一个设计良好的工具应该只需要少量的文档,或者根本不需要文档。SDK就是我们开发人员手中的工具,如果按照这句话来说的话,Android在很多方面设计的不够合理,因为很多类你即使认真读了文档(Android的文档也有待改进和完善),用起来也不是得心应手。个人认为Scroller就是一个例子。在具体说如何实现滚动之前,我们先来谈谈滚动的实质是什么。
滚动包含两种情形,一种是用户手指始终与屏幕接触,并在屏幕上滑动,此时View随着手指的滑动而滚动;另一种是用户快速的在屏幕上滑动后,手指离开屏幕,而View在手指离开屏幕后仍以一定的初始速度滚动,直到速度降为0,或者滚动到了view的两端。因此滚动可以实际上就是,View中的点在一定时间内的运动,本质上可以说是一定时间内由于View位置的改变而产生的一段动画
。既然是动画,那么就包含以下要素:
- 动画的时间
- 动画初始状态
- 动画中每一帧的状态
既然滚动也是动画,那么自然也需要设置上述状态,并需要根据动画中的每一帧来更新View。
浅谈Android使用起来不如iOS流畅的原因
网上很多人讨论Android手机使用起来没有iOS流畅的原因,之前在国外的论坛和Google+上见到过相关的讨论,记得还有google的Android技术负责人对相关的技术进行了澄清,在知乎上我们也可以看到类似的讨论。这里我们从不同的方面说一下,我们“感觉”Android不够流畅的原因。首先,我想强调一下,android系统在某些机器上,或者某些app不够流畅,并不是由于Android存在某些技术缺陷导致的,网上说的“没有硬件加速”、“屏幕反应延迟大”之类的原因都是不成立的。Android早就支持了硬件加速,如果真的是手机屏幕灵敏度导致了使用上的不流畅,那只能说你买的手机太挫了。
java并发编程之Volatile关键字
####并发程序概述
Android提供了很多并发用的工具,最基本的包括AsyncTask,handler-thread,但这些并发工具依然是基于Java的并发机制的,例如AsyncTask就是利用Java的线程池来安排多个线程的执行,并且由于多线程编程的复杂性,加深对java并发编程的理解有助于我们在开发中更加得心应手。
在并发过程中,有两个问题需要需要我们注意:互斥性和可见性。
互斥性比较容易理解,当有多个线程访问某共享变量时,为了保证程序执行的一致性和正确性,我们必须使用互斥,来保证在某一时刻只能有一个线程对共享变量进行访问。代码示例如下:1
2
3
4
5
6
7
8
9public class safeCounter {
private int counter = 0;
public synchronized int getCounter() {
return counter;
}
public synchronized void increaseCounter() {
counter++;
}
}
从上面代码可以看到,为了保证计数器的正常工作(当然是在多线程环境下),我们必须通过加锁来实现互斥,因为count++语句并不是原子性的,它包含读取counter值,将counter值加1和写回counter值三个操作,而加锁的目的之一就是保证这三步操作的完整性,实现整个操作的互斥,避免多个线程同时执行而引起混乱。而另一个目的就是可以保证可见性。
Android UI设计中FrameLayout的使用
Android系统提供了很多的界面Layout布局,LinearLayout主要是用来横向或者纵向显示,RelativeLayout可以控制控件之间的相对位置关系,类似于iOS当中的AutoLayout,这两者在平时的开发中都比较常用,而另一个FrameLayout提供了比这两者更加灵活的布局方式,利用FrameLayout我们可以达到子控件相互重叠的效果(Overlay)。看图:
Android Property Animation
与iOS相比Android中的动画稍逊一筹。在iOS中,View属性的改变在大多数时间会自动触发相应的动画,比如view位置的移动,view透明度的变化等,都会通过动画的形式展现出来,这样很容易带给用户很好的体验,使用户感觉到系统的行为是流畅而且连贯的;但是在Android系统中,无论是OS自带的app,还是第三方的app,很少有表现流畅的动画,界面之间的的切换往往不能给人连贯的感觉,而是瞬间内容的改变,比如Expandable List View的Group展开,完全没有动画效果,不得不说确实很不友好。
产生这种不同的原因可以说有几个方面:
首先,从系统机制来看,iOS将动画融入到了系统的各个方面,当我们对iOS中View的属性改变时,很多动画就会被自动触发;而Android如果想有动画效果,就必须由开发人员实现。
再者,在使用iOS的过程中,用户已经习惯了各种友好的动画,作为一名开发者,在开发中会自然而然的将动画考虑在内,开发者主观上就将动画作为判断app质量的一个方面;而在Android中,带有友好动画的app很少,因此大部分开发者也就没有重视动画效果(开发者果真都是懒惰的啊)。
第三,iOS中提供的动画框架对于开发者非常友好,Core Animation除了具有强大的功能,有好的接口和文档使开发者用起来得心应手;Android虽然也提供了多种不同的动画机制,但是很多看起来简单并且普遍的动画,比如ExpandableListView 中Group展开的动画,实现起来确实比较麻烦。
不过用户友好的、有意义的动画已经包含在google提出的Material Design中,下一代的Android L应该在动画方面会有很大的改善,但是app由于需要兼容不同版本的Android,想要完全改变android app在动画方面的表现还需要不短的时间。
Android SQLite Demo
之前简单学习了下SQLite的相关知识,这篇文章我们来看使用SQLite的一个简单的例子,例子中我们会使用如下的三个表格,进行数据库的创建,插入数据,和查询操作。可以到这里下载例子代码
首先,我们需要介绍一下Android中提供的使用SQLite的接口以及使用方法。
###Android中SQLite接口介绍###
SQLiteOpenHelper和SQLiteDatabase是我们在Android提供的与SQLite相关的主要类:
- SQLiteOpenHelper用于数据库的管理,包括数据库和数据表格的创建,数据库的升级等
- SQLiteDatabase主要提供了操作数据的接口,包括插入,查询,执行SQL语句等
Android Sqlite(一)
SQLite 概述
与PC比较,移动平台在可用内存和处理器计算能力方面仍有不足,SQLite作为一个轻量级的数据库,由于自身体积小巧,占用内存少等原因成为了诸多移动系统支持的主要数据库,Android,iOS,Blackberry都对SQLite有很好的支持。
- 易于使用
- 内存占用低
- 可以免费使用
无疑是SQLite成为移动平台首选的主要原因。作为数据库Library,SQLite的大小不到500K,核心功能库不到300K,运行时需要的最小栈空间仅为4K,要求堆空间也只有100K。这些无疑对嵌入式系统充满了诱惑,可以说是手机、PDA和MP3等类似设备的首选。虽然SQLite是可以免费使用,但是代码的质量没有因此而受影响,每一个SQLite发布版本都通过了很严格的测试,在SQLite的官网上我们可以看到下面这段话,让人对这个开源团队肃然起敬:
We the developers hope that you find SQLite useful and we charge you to use it well: to make good and beautiful products that are fast, reliable, and simple to use. Seek forgiveness for yourself as you forgive others. And just as you have received SQLite for free, so also freely give, paying the debt forward.
SQLite的特性
与传统的数据库系统相比,SQLite有很多能够吸引嵌入式设备的特性,
- 不像多数的PC数据库系统,SQLite没有Server的概念
- SQLite将所有的数据保存在同一个文件当中
- 相对于大型数据库,SQLite只支持部分的数据类型
- SQLite中对于字段的长度没有限制
- SQLite是跨平台的(64位与32位,大端与小端系统)