Android 线程中通过回调方式更新界面UI.

    有些时候,我们的APP需要访问网络或请求网络资源时,需要等待数据响应,如果不使用线程方式,主界面(线程),是处于阻塞状态的,不能操作其它UI,这时给用户的感觉也是差差的。

为了给用户一个友好的交互界面,使用线程方式,是比较合理的。

以下一段,是我使用线程与回调方式更新UI的代码片段;


一、首先定义一个线程回调的类,继承自Handler

/**
* 定义一个回调函数,内部类,在这里处理所有的上传下载,回调函数将根据msg.what的返回值,做不同的处理;

* @version 1.0
* @author 版权所有:[email protected] create by 2014-3-29
* */
class MyHandler extends Handler {

@SuppressLint("HandlerLeak")
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub

switch (msg.what) {
case 100:
// 如果线程返回100,表示下载学员信息成功,可进行存储处理,也可以在这里添加一个更新UI界面的方法。例如这里的SPD。;
spd.close();
saveGrantInfo(msg.getData().toString());
break;

case -100:
Log.d("数据下载失败", "失败原因:" + msg.getData().toString());
spd.close();
showToast = new ShowToast(MainActivity.this,"数据下载失败,请确定网络连接正常。并重新尝试,CODE:0404");
showToast.showDefaultIMG(2);
break;

default:
break;

}

super.handleMessage(msg);
}





二、定义一个基于http请求的下载方法,该下载方法,使用了线程方式。
/**
* 下载数据方法,下载的数据统一的返回给handler类;
* 定义一个下载线程,可以接受不同URL,返回的数据封闭在msg.data对象中;线程操作成功或网站访问成功,返回ture,失败则返回false

* @version 1.0
* @author 版权所有:[email protected] create by 2014-3-29
* @param url
*            : 接受特定的URL,例如:http://www.iceboard.net
* @param msgWhat
*            : 返回的msgWhat标量,通过不同的返回值,回调函数进行不同的操作;100:表示下载学员信息
*            ;200:表示下载考题;-100:表示下载过程出错
* */
public boolean downLoadInfomation(final String url, final int msgWhat) {


// 状态记录器设置为真;
flag = true;
// Log.d("拼装的URL是:", url);
// 开始一个线程,并实例化Runable对象,其中包括以下一些对象
new Thread(new Runnable() {


@Override
public void run() {
// TODO Auto-generated method stub


try {


URL realUrl = new URL(url);
URLConnection conn = realUrl.openConnection();
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
conn.connect();
//Log.d("线程中", "已经连接上来了" + url);
Log.d("登录", "已经连接上了服务器!");
// 定义
// 一个消息传递器,里面包括了消息标记号。下载的数据,存储在MSG的data容器中。最后调用回调函数将消息传递器返回给回调函数处理;
Message msg = new Message();
msg.what = msgWhat;
BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line, resultLine = "";


// 形如循环读取数据流;直到结束;
while ((line = br.readLine()) != null) {
resultLine += line;
}
// 定义 bundle容器,主要用于存储数据,下载的数据;
Bundle bundle = new Bundle();
// 将下载的数据流,压入bundle容器;
bundle.putString("data", resultLine);
// 将bundle容器内容,存入MSG消息传递器中;
msg.setData(bundle);
// 发送消息给回调函数。回调函数将开始处理
handler.sendMessage(msg);


} catch (Exception e) {
// TODO: handle exception
// 线程下载过程出现错误,设置标记为false,并输入错误信息,便于调试;
Message msg = new Message();


e.printStackTrace();
msg.what = -100;
Bundle b = new Bundle();
b.putString("data", e.getMessage());
msg.setData(b);
handler.sendMessage(msg);
}


}
}).start();// start()开启线程执行;


return flag;// 返回flag状态


}




三、使用时如下:


在主界面中,先声明一个回调函数 。


public class MainActivity extends Activity {

    private  MyHandler  handler = null;
    private Button bt_get;
    private ShowProgressDiaglog spd = null;

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


handler = new MyHandler();
bt_get=(Button) findViewById(R.id.bt_get);
bt_get..setOnClickListener(new OnClickListener() {


@SuppressLint("NewApi")
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String user = et_user.getText().toString();
String pass = et_pass.getText().toString();
                                

                                spd = new ShowProgressDiaglog("设备授权","正在连接服务器,等待授权。。。。。", 1, 0, 0,MainActivity.this);

// 如果账号和密码没有输入。则提示输入账号和密码
downLoadInfomation( 这里填URL地址, 100); //后面定义的返回标量,决定回调函数中要拦截的标量
}
});

}
}


四、最后,再呈上一个自定义的对话框的类



public class ShowProgressDiaglog {


private ProgressDialog pd=null;
private int Style=0;
private int progress=0;
private String title="";
private String message="";
private Context context;
private int maxprogress=100;


/**
* 对话框对象,构造一个对话框的基本对象;
* @param title : 显示对话框的标题;
* @param message :显示对话框的消息
* @param style :定义显示进度杠条的样式;1 表示圆形进度条,0表示水平进度条;
* @param progress :进度条的当前长度 
* **/
public ShowProgressDiaglog( String title, String message,
int style, int maxprogress, int progress, Context context ) {
super();
this.pd = new ProgressDialog(context); 
Style = style;
this.progress = progress;
this.maxprogress=maxprogress;
this.title = title;
this.message = message;
this.context = context;
}
/**
* 打开对话框。
* */
public void open(){ 
//设置进度条风格,风格为圆形,旋转的
if (Style==1) {
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
}else if(Style==0) {
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
}
//设置进度条进度
if (progress>0) {
pd.setProgress(progress);

//设置标题
pd.setTitle(title);
//设置显示信息
pd.setMessage(message);

pd.setIcon(R.drawable.warning);
//设置ProgressDialog 标题图标 
pd.setIndeterminate(false);
//设置ProgressDialog 的进度条是否不明确
pd.setCancelable(false);
//设置ProgressDialog 是否可以按退回按键取消
pd.show();
}


/**
* 关闭对话框
* */
public void close(){
pd.dismiss();
}

public ProgressDialog getPd() {
return pd;
}


public void setPd(ProgressDialog pd) {
this.pd = pd;
}


public int getStyle() {
return Style;
}


public void setStyle(int style) {
Style = style;
}


public int getProgress() {
return progress;
}


public void setProgress(int progress) {
this.progress = progress;
}


public String getTitle() {
return title;
}


public void setTitle(String title) {
this.title = title;
}


public String getMessage() {
return message;
}


public void setMessage(String message) {
this.message = message;
}


public Context getContext() {
return context;
}


public void setContext(Context context) {
this.context = context;
}
public int getMaxprogress() {
return maxprogress;
}
public void setMaxprogress(int maxprogress) {
this.maxprogress = maxprogress;
}
}



发布了39 篇原创文章 · 获赞 8 · 访问量 14万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章