1.关于构造Message对象
Message 可以通过 new Message(),也可以通过handler.obtainMessage()。两种的区别,后者无需在内存中重新开辟空间,而是直接从消息队列池中取出。
/** * Returns a new {@link android.os.Message Message} from the global message pool. More efficient than * creating and allocating new instances. The retrieved message has its handler set to this instance (Message.target == this). * If you don't want that facility, just call Message.obtain() instead. */ public final Message obtainMessage() { return Message.obtain(this); }
从from the global message pool中可以看出。
2.实际开发中什么情况下用到了handler.
需求:在搜索结果页只有一个ListView,当用户输入的关键词为空的时候,从SharePreference中取出10个历史词,当用户每输入一个关键词,都会触发获取联想词的异步任务。当用户点击搜索按钮后,当前listview显示搜索结果。历史词、联想词、搜索结果共用一个ListView。分别使用adapterHistory,adapterAssociation,adapterSearch.
问题:在使用TextWatcher监听EditText中关键词变化的过程中,如果用户快速把搜索框中的关键词删掉的过程中,这个过程中会触发联想词的异步任务。当用户删完关键词,ListView显示出了历史词,但是由于联想词的异步任务相比本地拿SharePreference的速度要慢,容易导致当前listview显示的结果是联想词的adapter。
解决办法:在执行不同类型任务之前,执行如下代码
if(handler.hasMessages(1)){ handler.removeMessages(1); } Message msg = handler.obtainMessage(); msg.what = 2; handler.sendMessage(msg);如果消息队列中有另一个任务的消息,先把它清空。
3.在联想词触发的过程中,如果可以通过sendMessageDelayed()方法延迟触发。
if (handler.hasMessages(1)) { handler.removeMessages(1); } Message msg = handler.obtainMessage(); msg.what = 1; msg.obj = key; handler.sendMessageDelayed(msg, 300);