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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章