`
zhenzxie
  • 浏览: 66916 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Android学习之路——3.Handler的子类

阅读更多
API中介绍Handler的子类有四个,分别是:
AsyncQueryHandler, WorkerHandler, HttpAuthHandler, SslErrorHandler。
其中WorkerHandler是AsyncQueryHandler的内部类,另一个内部类是WorkerArgs,它们俩是帮助AsyncQueryHandler来实现异步处理ContentResolver事务的。

(一)AsynQueryHandler和WorkerHandler
1.AsyncQueryHandler和AsyncQueryHandler.WorkerHandler在android.content包下,作用是帮助更轻松的处理需要异步的ContentResolver查询等事务。(API中原文是:A helper class to help make handling asynchronous ContentResolver queries easier.)

2.AsyncQueryHandler是抽象类,所以要使用它就必须继承它,并实现onXXXXComplete()方法,处理当查询等事务完成时应该做的操作。

3.AsycQueryHandler中有一个WorkerArgs内部类,保存着一些数据。
请看贴图:


子类在实现自己的handlerMessage()方法时,调用super.handleMessage(Message)时,应注意Message中的obj参数可以向下转化为WorkerArgs对象。AsycQueryHandler的startXXXX()方法使用WorkArgs对象来传递执行所需要的参数,并把WorkArgs对象赋给Message.obj。Message中的arg1中保存着要进行的操作,AsycQueryHandler中有四个静态的实例域代表四种操作。
请看startUpdate()的实现:



4.当一个子类继承AsycQueryHandler,并实现自己的OnXXXXComplete()方法时,如果子类对象调用startXXXX()方法,那么事务处理的顺序可以清楚的知道。首先需要明确这些事务的处理是在主线程之外的线程(通过HandlerThread实现,应该也可以把主线程的Looper传递给它吧。)进行的。但是多个子类实例也只会开启一个线程,使用同一个Looper对象。当创建对象的时候,会创建另一个Handler对象那就是WorkerHandler对象。
请看AsyncQueryHandler的构造方法:


然后当调用startXXXX方法时,依据参数创建一个WorkArgs对象赋给新获得的Message对象的obj,Message对象会传递给上面的WorkHandler对象的消息队列,然后处理(参看上第二图)。处理完后WorkHandler对象会将消息传递给AsycQueryHandler对象的消息队列,然后处理,这时候的处理是调用onXXXXComplete方法,来实现回调的。
请看图:


看了这个过程可以知道子类没有必要自己实现handleMessage()方法。只需要创建AsycQueryHandler子类对象,并实现自己的OnXXXXComplete()方法,然后调用startXXXX()方法。

5.使用方法示例:(示例来自网络)

// 定义一个handler,采用的是匿名类的方式,只处理query,因此只重写了onQueryComplete函数:
queryHandler = new AsyncQueryHandler(this.getContentResolver()){ // 传入的是一个ContentResolver实例,所以必须在OnCreate后实例化该Handler类
@Override
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
         // 在这里你可以获得一个cursor和你传入的附加的token和cookie。
         // 该方法在当前线程下(如果传入的是默认的Looper话),可以自由设定UI信息
     }
};
//调用时只需要调用startQuery(int token, Object cookie, ContentURI uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)函数即可:
queryHandler.startQuery(token,cookie,uri, projection, selection, selectionArgs, sortBy);

补充:
在看AsyncQueryHandler的回调时,它比不是通过接口来实现的,而是通过继承来实现的。
先看下面一段代码。


public class C {

	public static void main(String[] args) {
		A a = new B();
		a.deal("Learn Android Everyday");//一
		new B().handler("Learn Android Everyday");//二
	}

}

class A {

	public void handler(String arg) {
		System.out.println("In the class A handler :" + arg);
		onHandler(arg);
	}

	public void onHandler(String arg) {

		System.out.println("In the class A onHandler :" + arg);
	}
	
	public void deal(String arg){
		System.out.println("In the class A deal :" + arg);
	}
}

class B extends A {

	@Override
	public void handler(String arg) {

		super.handler(arg);
	}

	@Override
	public void onHandler(String arg) {

		System.out.println("In the class B onHandler :" + arg);
	}
	
	@Override
	public void deal(String arg){
		System.out.println("In the class B deal:" + arg);
	}
}

运行的结果是:
In the class B deal:Learn Android Everyday
In the class A handler :Learn Android Everyday
In the class B onHandler :Learn Android Everyday
在“一”处:体现了Java的继承实现的动态绑定,调用的是子类的deal()方法。
而“二”处:调用的是子类的handler()方法,但是子类的方法调用了父类的方法。在父类的handler()方法里在调用onHandler()方法,这时候它回调了子类的onHandler()方法。这也是AsyncQueryHandler回调的实现方法。


(二)HttpAuthHandler和SslErrorHandler
1.类的定义里除了两个return false之外没有任何实现,自己继承吧。API原文里讲:HTTP authentication request that must be handled by the user interface. WebView creates the object and hands it to the current WebViewClient, which must call either proceed(String, String) or cancel(). 估计大概是和WebViewClient配合使用吧。

2.类的定义里没有任何实现。用于处理Ssl错误的,当作参数传递给BrowserCallback.displaySslErrorDialog,接受用户的回应。(API中原文:class responsible for handling SSL errors. This class is passed as a parameter to BrowserCallback.displaySslErrorDialog and is meant to receive the user's response。不知道翻译的对不对)

3.这两个类来自android.webkit包,类里的方法都是没有实现的,但又不是写成abstract。大概是想让子类更好继承吧。
  • 大小: 18.3 KB
  • 大小: 9.9 KB
  • 大小: 16.8 KB
  • 大小: 17.7 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics