总以为自己对Handler比较了解,但今天发现还是不了解,以后写代码得好好的看看android doc了,这样才能理解的更深。
一直以为Handler.post(Runnable)为开启一个线程,所以出现了一下问题。
我定义了一个Runnable用来实现短信的分段读取:
private class SubSectionRunnable implements Runnable{
private Cursor mCursor;
private final int RECIPIENT_IDS = 3;
private final int SNIPPET = 4;
private String mRecipient;
private String mSnippet;
private String mNumber;
private Long mSnippetCS;
private String mName;
private String mThreadId;
private final int mFirstQueryStep = 20;
private final int mOtherQueryStep = 80;
private Long mDate = 0l;
private boolean mIsFirstQuery = true;
private TestSpeed mTestSpeed1 = new TestSpeed();
private TestSpeed mTestSpeed2 = new TestSpeed();
@Override
public void run() {
mTestSpeed1.loadBeginTime();
mCursor = getContentResolver().query(THREADS_URI,
ALL_THREADS_PROJECTION, null, null, "date DESC limit " + mFirstQueryStep);
while(mCursor != null && mCursor.getCount() > 0){
Log.i("xiao", "onPostExecute new " + mCursor.getCount());
ConversationInfo conver = new ConversationInfo();
mConversationInfoPreviousList.add(conver);
while(mCursor.moveToNext()){
mThreadId = mCursor.getString(ID);
mDate = mCursor.getLong(DATE);
mRecipient = mCursor.getString(RECIPIENT_IDS);
mSnippetCS = mCursor.getLong(SNIPPET_CS);
if(mSnippetCS ==0){
mSnippet = mCursor.getString(SNIPPET);
}
else{
try {
mSnippet = new String(
mCursor.getString(SNIPPET).getBytes("ISO8859_1"), "utf-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Cursor cr = getContentResolver().query(
Uri.parse("content://mms-sms/canonical-addresses"),
new String[] { "_id", "address" }, "_id=?",
new String[] { mRecipient }, null);
if(cr != null && cr.moveToFirst()){
mNumber = cr.getString(1);
mName = getContactNameByPhone(cr.getString(1));
}
else{
mNumber = "";
mName = null;
}
ConversationInfo conversation = new ConversationInfo(mRecipient, mSnippet, mNumber, mSnippetCS, mName, mThreadId);
mConversationInfoPreviousList.add(conversation);
}
for( int i = 0; i < mConversationInfoPreviousList.size(); i++){
try {
mConversationInfoAdapterList.add(mConversationInfoPreviousList.get(i).clone());
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
mCursor.close();
if(mIsFirstQuery){
Message message = new Message();
message.what = 1;
boolean flag1 = mGetMmsHandler.sendMessage(message);
Log.i("xiao", "flag1 = " + flag1);
mIsFirstQuery = !mIsFirstQuery;
mTestSpeed1.loadEndTime();
mTestSpeed1.printDuration();
}
Message message = new Message();
message.what = 2;
boolean flag2 = mGetMmsHandler.sendMessage(message);
Log.i("xiao", "flag2 = " + flag2);
mTestSpeed2.loadEndTime();
mTestSpeed2.printDuration();
mCursor = null;
mTestSpeed2.loadBeginTime();
mCursor = getContentResolver().query(THREADS_URI,
ALL_THREADS_PROJECTION, "date < " + mDate, null, "date DESC limit " + mOtherQueryStep);
}
}
public String getContactNameByPhone(String number) {
String name = "";
Uri personUri = Uri.withAppendedPath(
ContactsContract.PhoneLookup.CONTENT_FILTER_URI, number);
try{
Cursor cur = getContentResolver().query(personUri,
new String[] { PhoneLookup.DISPLAY_NAME },
null, null, null );
if(cur != null){
if( cur.moveToFirst() ) {
int nameIdx = cur.getColumnIndex(PhoneLookup.DISPLAY_NAME);
name = cur.getString(nameIdx);
}
cur.close();
}
}
catch(Exception e){
Log.i("xiao", "" + e.getMessage());
}
return name;
}
}
然后定义了一个Handler用来更新界面:
private class GetMmsHandler extends Handler{
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
int what = msg.what;
switch(what){
case 0:
showProgress();
mGetMmsThread.start();
break;
case 1:
hideProgress();
break;
case 2:
Log.i("xiao", "handleMessage 22222222222222");
mConversationAdapter.notifyDataSetChanged();
break;
}
}
}
但我发现每次都是等所有的短信读取完毕后才会打印几次handlerMessage 222222222222信息,所以界面更本没有出现先显示一些,然后陆续加载的过程,我就很奇怪,为什么会会是这样呢,我在mGetMmsHandler.sendMessage后加了判断,看这个消息是否发送成功,验证后是发送成功了,我就查看Handler的doc,原来post(Runnable)是把这个Runnable加到当前的消息队列中,所以等这个Runnable处理完毕后才会处理接受到的多次what为2的消息。