Android应用开发过程中一些容易被忽略的知识点。
1.ListView中关于Item和convertView之间重用的问题
如果你有100条数据,但是手机屏幕的高度只能够显示9个,其实在ListView中只会加载10个View而不是一口气加载100个,多出来的那一个View是用来给convertView重用的,这样当你上拉或者下拉的过程中其实只是这10个View在来来回回的被重用
2.线程优先级
如果我们自己要写一条线程去执行,需要在Runnable.run()方法的开始的地方调用 setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND)方法把该线程的优先级设置为后台运行级别,这样就减少了此线程和UI线程之间的资源竞争,从而让资源优先分配给UI线程,保证流畅度。
class PhotoDecodeRunnable implements Runnable {
...
/*
* 定义要在这个任务中执行的代码
*/
@Override
public void run() {
// 把当前的线程变成后台执行的线程
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
...
}
...
}
3.findViewById方法
如上图所示,当Android将xml的layout文件加载至内存中后其实是以 控件树的形式来管理layout的层次的,所以当通过findviewbyid获得根结点的引用后,如果想获得这个结点下子VIEW的引用可以直接用根结点的引用来获得,例如图上右侧container.findviewbyid的形式,这样可以缩小查找的范围,android会直接从子树的范围内寻找,从而提升效率。
4.AsyncTask
如上图所示,AsyncTask常用的4个方法中只有doInBackground()方法是在后台线程中运行的,其余3个都是在主线程中运行。并且AsyncTask应该只用于和当前Activity生命周期紧密关联且执行时间最多一两秒的短时间任务,具体详见
http://blog.youkuaiyun.com/hguang_zjh/article/details/41518483
5.ArrayAdapter
当我们使用ArrayAdapter填充listview的时候,源数据更新后,需要更新ListView中的视图时可以调用ArrayAdapter的下面这两个方法:
/**
* Adds the specified object at the end of the array.
*
* @param object The object to add at the end of the array.
*/
public void add(T object) {
synchronized (mLock) {
if (mOriginalValues != null) {
mOriginalValues.add(object);
} else {
mObjects.add(object);
}
}
if (mNotifyOnChange) notifyDataSetChanged();
}
/**
* Adds the specified Collection at the end of the array.
*
* @param collection The Collection to add at the end of the array.
*/
public void addAll(Collection<? extends T> collection) {
synchronized (mLock) {
if (mOriginalValues != null) {
mOriginalValues.addAll(collection);
} else {
mObjects.addAll(collection);
}
}
if (mNotifyOnChange) notifyDataSetChanged();
}
代码中最后都会调用notifyDataSetChanged()方法,它的作用是通知ListView去更新视图,add()和addAll()的区别是add是将集合中的数据一条一条的取出来后传给add方法然后去更新视图,这样会造成每增加一条数据都要重新绘制一次ListView,但是addAll方法可以将整个集合传给它然后只需要更新一次ListView就可以了(addAll方法只能用于3.0及以上的版本)
6.关于对Content Provider的理解
我们知道Content Provider可以作为对外部暴露我们APP数据的一种安全的机制来使用,但是假设我们不需要对外部APP暴露数据那么是不是我们就可以不用Content Provider了呢。
其实Content Provider也可以作为View访问底层数据比如SQlite时的一个中间层,这样UI只需要从Content Provider读取数据就可以了,从而不需要关心底层SQlite的语句实现等等信息,而且若SQlite数据结构有变动也只需要改动Content Provider就可以了,另外当我们使用CursorLoader或者Sync Adapter时也需要Content Provider的支持。
orm框架与content provider对比:
http://blog.youkuaiyun.com/u012565107/article/details/20042339