1 Android中Handler的作用
看看SDK中是怎么介绍的:
一个handler允许你发送和处理 Message和线程的MessageQueue的Runnable对象。每个handler实例是与一个单独的线程和该线程的消息队列相关。当你创建一个新的handler,它必然与创建它的线程的线程/消息队列相联系 - 从这一点上,它会提供消息和的Runnable到消息队列中,并当它们在消息队列中出来时执行它。
handler的主要用途有两个:(1)对消息和Runnable进行延迟,并在未来的某个点执行;(2)将一个即将在其它队列中执行的Action进行排队。
调度的消息与下列方法相关: post(Runnable), postAtTime(Runnable, long), postDelayed(Runnable, long), sendEmptyMessage(int), sendMessage(Message), sendMessageAtTime(Message, long), and sendMessageDelayed(Message, long) 。以post开头的方法可以将Runnable对象排队到消息队列中;以sendMessage开头的方法将包含一些 bundle数据的Message,这些消息将在 handleMessage(Message) 中方法中被处理。
当posting 或sending到处理程序时,您可以使它尽快执行当消息队列准备好时,或指定一个延迟或处理的绝对时间在它执行之前。后两个允许您执行 timeouts, ticks, 和其他基于时序的行为。
当应用程序创建一个进程,它的主线程维护一个消息队列,专门用于运行管理顶层的应用程序对象(活动,广播等)和他们所创建的任何窗口。您可以创建自己的线程,通过Handler与主应用程序线程进行通信。这和之前的一样,用SendMessage函数方法,但是从你的新线程。然后Runnable或消息就会被排入消息队列,并在适当的时候处理。
翻译的比较绕口,解释如下:
Android也有消息队列和消息循环,但Android系统的消息队列和消息循环都是针对具体线程的,特定线程的消息只能分发给本线程,不能进行跨线程,跨进程通讯。Handler的作用是把消息加入特定的消息队列中,并分发和处理该消息队列中的消息。
从上面的SDK可以看出, Handler有两个作用:处理规划自身的线程的消息队列,比如加入一些延时,或者处理带bundle数据的Message,而Message在Handler中的handleMessage中处理;第二个作用就是与Activity线程进行通信,也就是UI线程,用的也是SendMessage方法,只不过是在自己创建的工作线程中调用。
2 将取得weibo数据的方法放到其它线程中
为了不是主线程阻塞太长时间,引起ANR异常,应该(1)在主线程中新建个Handler对象,并重写其handleMessage方法;(2)把网络操作放到另一个线程中;(3)处理完毕后,得到主线程的handler对象,和新建Message对象,然后SendMessage,并在handleMessage进行处理。
改后的HomeTimeLineActivity.java如下:
package masofeng.zwd;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import weibo4android.Status;
import weibo4android.User;
import weibo4android.Weibo;
import weibo4android.WeiboException;
import weibo4android.androidexamples.OAuthConstant;
import weibo4android.http.AccessToken;
import weibo4android.http.RequestToken;
import android.app.Activity;
import android.app.ListActivity;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
public class HomeTimeLineActivity extends ListActivity implements OnItemClickListener,OnItemLongClickListener{
private ListView lv;
private MylistAdpter mla;
private List<Status> homestatlsit;
private Weibo weibo;
private static final int REFRESH_STATUS = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hometimelinetab);
System.setProperty("weibo4j.oauth.consumerKey", Weibo.CONSUMER_KEY);
System.setProperty("weibo4j.oauth.consumerSecret", Weibo.CONSUMER_SECRET);
//新建一个RequestToken
RequestToken requestToken = new RequestToken("1364680900","f8f43ee3c2e6bb6e57d5354e0570237c");
//新建一个AccessToken
AccessToken accessToken = new AccessToken("32e03adb68945490be2ec246723f5bf5",
"d0b5c462e6e61fcfa43202a4354f8102");
//将RequestToken和AccessToken设到OAuthConstant单例中
OAuthConstant.getInstance().setRequestToken(requestToken);
OAuthConstant.getInstance().setAccessToken(accessToken);
weibo = OAuthConstant.getInstance().getWeibo();
weibo.setToken(OAuthConstant.getInstance().getToken(),OAuthConstant.getInstance().getTokenSecret());
lv = getListView();
lv.setOnItemClickListener(this);
lv.setOnItemLongClickListener(this);
new MyThread().start();
}
// 新建一个Handler类用来接受工作线程的消息,以更新UI
private Handler myhandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
// 更新UI
case REFRESH_STATUS:
mla = new MylistAdpter(HomeTimeLineActivity.this, homestatlsit);
lv.setAdapter(mla);
break;
}
}
};
// 新建一个线程内部类用来进行网络操作
class MyThread extends Thread {
@Override
public void run() {
try {
// 得到weibo的数据
homestatlsit = weibo.getFriendsTimeline();
// 得到主线程中的Handler的Message
Message msg = myhandler.obtainMessage();
// 设置Message的参数
msg.what = REFRESH_STATUS;
// 发送消息到主线程
myhandler.sendMessage(msg);
} catch (WeiboException e) {
e.printStackTrace();
}
}
}
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {
// arg2是在ListView中的位置,arg3是getItemId返回的值
Log.i("myweibo","onItemLongClick--->arg2:"+arg2+";arg3:"+arg3);
return false;
}
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// arg2是在ListView中的位置,arg3是getItemId返回的值
Log.i("myweibo","onItemClick--->arg2:"+arg2+";arg3:"+arg3);
}
}
//用于ListView的监听类
class MylistAdpter extends BaseAdapter{
private Context ctx;
private List<Status> adplist;
private LayoutInflater inflater;
//自定义构造函数,以取得List
public MylistAdpter(Context ctx1,List<Status> list) {
super();
adplist = list;
this.ctx = ctx1;
inflater = LayoutInflater.from(ctx);
Log.i("myweibo","listadpter--->construct!");
}
@Override
public int getCount() {
Log.i("myweibo","listadpter--->getCount:"+adplist.size());
return adplist.size();
}
@Override
public Object getItem(int position) {
Log.i("myweibo","listadpter--->getItem");
return adplist.get(position);
}
@Override
public long getItemId(int position) {
Log.i("myweibo","listadpter--->getItemId:"+position);
return position+10;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Status tmpstu = adplist.get(position);
convertView = inflater.inflate(R.layout.homelistitem, null);
TextView tv1 = (TextView)convertView.findViewById(R.id.ltmUserName);
tv1.setText(tmpstu.getUser().getName());
TextView tv2 = (TextView)convertView.findViewById(R.id.lsmContent);
tv2.setText(tmpstu.getText());
ImageView iv1 = (ImageView)convertView.findViewById(R.id.home_headicon);
if(!(tmpstu.getUser().getProfileImageURL()).equals("")){
iv1.setImageBitmap(WeiboUtil.getBitmapFromUrl(tmpstu.getUser().getProfileImageURL()));
}
ImageView iv2 = (ImageView)convertView.findViewById(R.id.lsmweiboPic);
if(tmpstu.getThumbnail_pic()!=""){
iv2.setImageBitmap(WeiboUtil.getBitmapFromUrlString(tmpstu.getThumbnail_pic()));
iv2.setVisibility(View.VISIBLE);
}
LinearLayout sublay = (LinearLayout)convertView.findViewById(R.id.subLayout);
Status retsta = tmpstu.getRetweeted_status();
if(retsta==null){
sublay.setVisibility(View.GONE);
}
else{
TextView tv3 = (TextView)convertView.findViewById(R.id.lsmretweedweibo);
tv3.setText("@"+retsta.getUser().getName()+":"+retsta.getText());
if(retsta.getThumbnail_pic()!=""){
ImageView iv3 = (ImageView)convertView.findViewById(R.id.subweiboPic);
iv3.setImageBitmap(WeiboUtil.getBitmapFromUrlString(retsta.getThumbnail_pic()));
}
}
return convertView;
}
}