· 第二部分是授权:\
· 第二部分是路径:\(如果没有指定ID,那么表示返回全部)。
由于URI通常比较长,而且有时候容易出错,且难以理解。所以,在Android当中定义了一些辅助类,并且定义了一些常量来代替这些长字符串的使用,例如下边的代码:
Contacts.People.CONTENT_URI (联系人的URI)。 在我们的实例MyProvider中是如下定义的:
public static final String AUTHORITY=\public static final String PATH_SINGLE=\public static final String PATH_MULTIPLE=\public static final Uri
content_URI=Uri.parse(\
5 Service如何向Activity传递数据
一个Android程序可以由多个Activity和Servier组成,在这些程序组件之间传递数据的方法有以下几种,每种方法都有其特定的使用途径。
5.1 原始数据类型
在Activity/Servier之间传递临时性的原始数据,可以使用Intent的putExtras方法来传递数据。
若传递的数据需要长久保存,则使用SharedPreference类来完成。
5.2 传递对象
当在Activity/Servier之间传递不需要长久保存的对象时,可以使用以下几种途径:
(1)通过Application类,每个Android应用程序都有一个Application类。当你在程序的AndroidManifest.xml中给Application设定一个名字时,你的程序中就必须有一个Application的子类。这个Application子类会被Android自动实例化,并且是一个全局性的类,它的生命周期和程序的生命周期相同,你可以把一些全局性的对象保存在Application类中。Application类可以通过getApplication()获得。
(2)通过HashMap of WeakReferences传递对象。当一个Activity需要向另外一个Activity传递对象时,可以使用一个关键字把对象存在一个HashMap中,并把这个关键字通过Internt的Extras发给目标Activity,目标Activity接到该关键字后使用该关键字把对象从HashMap中取出。
5.3 在Activity/Service之间传递需要长久保存的对象时,可以使
用以下的方式
1. 2. 3. 4.
Application Preferences Files
contentProviders SQLite DB
6 AsyncTask
6.1 底层处理
底层使用本地线程池机制:
1. 核心线程数:线程池中保存的线程数,包括空闲线程,默认为5个 2. 线程池中允许的最大线程数,固定为128个+10个阻塞线程
3. 当线程数大于核心线程数时,如果线程池中中线程数大于核心线程数5
超过一秒事,终止多余的线程,保留五个核心线程数。
4. 执行前用于保持任务的队列,此队列仅保持execute方法提交的
Runnable任务,固定容量为10 5. 执行程序创建新线程时使用的工厂
6.2 AsyncTask介绍
Android的AsyncTask比Handler更轻量级一些(只是代码上轻量一些,而实际上要比handler更耗资源),适用于简单的异步处理。
首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的。
Android为了降低这个开发难度,提供了AsyncTask。AsyncTask就是一个封装过的后台任务类,顾名思义就是异步任务。
AsyncTask直接继承于Object类,位置为android.os.AsyncTask。要使用AsyncTask工作我们要提供三个泛型参数,并重载几个方法(至少重载一个)。
AsyncTask定义了三种泛型类型 Params,Progress和Result。 Params 启动任务执行的输入参数,比如HTTP请求的URL。 Progress 后台任务执行的百分比。
Result 后台执行任务最终返回的结果,比如String。
使用过AsyncTask 的同学都知道一个异步加载数据最少要重写以下这两个方法:
doInBackground(Params?) 后台执行,比较耗时的操作都可以放在这里。注意这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作,通
常需要较长的时间。在执行过程中可以调用publicProgress(Progress?)来更新任务的进度。
onPostExecute(Result) 相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回
有必要的话你还得重写以下这三个方法,但不是必须的:
onProgressUpdate(Progress?) 可以使用进度条增加用户体验度。 此方法在主线程执行,用于显示任务执行的进度。
onPreExecute()这里是最终用户调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框。
onCancelled() 用户调用取消时,要做的操作
使用AsyncTask类,以下是几条必须遵守的准则: Task的实例必须在UI thread中创建; execute方法必须在UI thread中调用;
不要手动的调用onPreExecute(), onPostExecute(Result),
doInBackground(Params...), onProgressUpdate(Progress...)这几个方法;
该task只能被执行一次,否则多次调用时将会出现异常;
6.3 AsyncTask实现的原理和适用的优缺点
AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.
使用的优点: 简单,快捷
过程可控 使用的缺点:
在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来.
7 Handler
7.1 Handler异步实现的原理和适用的优缺点
1. Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的
MessageQueue(消息队列)。
2. Handler: 你可以构造Handler对象来与Looper沟通,以便push新消息
到MessageQueue里;或者接收Looper从Message Queue取出)所送来的消息。
3. Message Queue(消息队列):用来存放线程放入的消息。
4. 线程:UIthread 通常就是main thread,而Android启动程序时会替它
建立一个MessageQueue。
在Handler 异步实现时,涉及到 Handler, Looper, Message, MessageQueue四个对象,实现异步的流程是主线程启动Thread(子线程)运行并生成Message放到MessageQueue,Looper从MessageQueue中获取Message并传递给Handler,Handler逐个获取Looper中的Message,并进行UI变更。
使用的优点:
结构清晰,功能定义明确
对于多个后台任务时,简单,清晰 使用的缺点: 在单个后台异步
处理时,显得代码过多,结构过于复杂(相对性)
7.2 Handler介绍
Handler主要接受子线程发送的数据, 并用此数据配合主线程更新UI. 当应用程序启动时,Android首先会开启一个主线程, 主线程为管理界面中的UI控件,进行事件分发,更新UI只能在主线程中更新,子线程中操作是危险的。这个时候,Handler就需要出来解决这个复杂的问题。由于Handler运行在主线程中(UI线程中),它与子线程可以通过Message对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传递)Message对象(里面包含数据), 把这些消息放入主线程队列中,配合主线程进行更新UI。
7.3 Handler的特点
Handler可以分发Message对象和Runnable对象到主线程中, 每个Handler实例,都会绑定到创建他的线程中,
它有两个作用:
(1)安排消息或Runnable 在某个主线程中某个地方执行 (2)安排一个动作在不同的线程中执行 Handler中分发消息的一些方法 post(Runnable)
postAtTime(Runnable,long) postDelayed(Runnable long) sendEmptyMessage(int) sendMessage(Message)
sendMessageAtTime(Message,long) sendMessageDelayed(Message,long)
以上post类方法允许你排列一个Runnable对象到主线程队列中,
sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等
待更新.
7.4 综上所述
数据简单使用
AsyncTask:实现代码简单,数据量多且复杂使用
handler+thread :相比较AsyncTask来说能更好的利用系统资源且高效
8 ListView
8.1 ListView优化
8.1.1 简介
在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容,用户可以自由的定义listview每一列的布局,但当listview有大量的数据需要加载的时候,会占据大量内存,影响性能,这时候就需要按需填充并重新使用view来减少对象的创建。
ListView加载数据都是在public View getView(int position, View convertView, ViewGroup parent) {}方法中进行的(要自定义listview都需要重写listadapter:如BaseAdapter,SimpleAdapter,CursorAdapter的等的getvView方法),优化listview的加载速度就要让convertView匹配列表类型,并最大程度上的重新使用convertView。
8.1.2 getview的加载方法一般有以下三种种方式:
1. 最慢的加载方式是每一次都重新定义一个View载入布局,再加载数据 2. 正确的加载方式是当convertView不为空的时候直接重新使用
convertView从而减少了很多不必要的View的创建,然后加载数据 3. 最快的方式是定义一个ViewHolder,将convetView的tag设置为
ViewHolder,不为空时重新使用即可 8.1.3 补充
当处理一些耗时的资源加载的时候需要做到以下几点,以使你的加载更快更平滑: 1. 适配器在界面主线程中进行修改