应用程序所有UI组件的创建,UI刷新,处理用户输入事件等都是运行于UI线程(也叫main线程),除了main线程外,程序可能还得需要其他线程(work线程),例如程序从服务器下载等比较耗时的操作,这些功能不能放在main线程中进行处理,否则,程序将无法响应用户的输入事件,甚至会出现ANR或是FC。UI组件的刷新等只能在main线程中进行,因此work线程的处理结果可能需要向main线程进行反馈,因此得处理线程间的通讯,线程间的通讯方法有:
1. Handler
使用sendMessage() 或 post() 等方法(得覆盖Handler类的handleMessage()方法)
2. 可在work线程中使用方法runOnUiThread(),实现代码块在UI线程中运行,例如:
1)runOnUiThread(Runnable)
Runnableaction = new Runnable() {
@Override
publicvoid run() {
mTextView.setText("下载完成");
}
};
2) View.post(Runnable)
3) Handler.post(Runnable)
4) View.postDelayed(Runnable, 1000)
5)Handler.postDelayed(Runnable, 1000)
3. 使用系统api AsyncTask,该类可部分代替Handler,同时不需要自己创建Thread
如何使用该类:
1. 继承AsyncTask,指定泛型参数
例如:classMyAsycnTask extends AsyncTask<URL, Integer, String>
2. 覆写1)doInBackground() 在work thread执行耗时操作
2)onPostExecute() 在UI执行,
当doInBackground()方法执行完成之后被调用,
doInBackground()的返回值作为参数传进来
3. 执行任务:
创建对象,并调用execute()方法执行
例如:
MyAsycnTask myAsycnTask= new MyAsycnTask();
myAsycnTask.execute(null);
刷新进度:
当用户开启一个耗时操作时,程序中应该向用户反馈进度。在该类中刷新进度方法:
覆写onProgressUpdate()方法,该方法在UI线程中执行,刷新进度条的进度以及其它UI;然后在在doInBackground()方法中调用,publishProgress()方法传递消息,相当于Handler.sendmessage()方法
示例程序代码:
程序通过获取静态数据来模拟向网络服务器下载数据,获取数据的操作放在异步任务AsyncTask里完成。程序的主要代码:
//MainActivity.java
package com.wy;
import java.util.List;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Pair;
import android.view.View;
importandroid.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extendsActivity implements OnClickListener,
android.content.DialogInterface.OnClickListener{
privateint mPage = 2;
privatestatic final int PROGRESSDIALOG = 1;
privateProgressDialog mDlg;
privateTextView mtTextView;
privateMyAsyncTask mTask;
privateButton mButton;
classMyAsyncTask extends
AsyncTask<Integer,Void, Pair<Boolean, List<String>>> {
protectedPair<Boolean, List<String>> doInBackground(Integer... params) {
intpage = params[0];
Pair<Boolean,List<String>> pair = Data.getRows(page);
returnpair;
}
@Override
protectedvoid onPostExecute(Pair<Boolean, List<String>> result) {
//TODO Auto-generated method stub
mDlg.cancel();
List<String>data = result.second;
mtTextView.setText(data.toString());
mPage++;
mButton.setEnabled(true);
}
}
/**Called when the activity is first created. */
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mButton= (Button) findViewById(R.id.button1);
mButton.setOnClickListener(this);
mtTextView= (TextView) findViewById(R.id.tvShowData);
}
@Override
publicvoid onClick(View v) {
//TODO Auto-generated method stub
mTask= new MyAsyncTask();
mTask.execute(mPage);
showDialog(PROGRESSDIALOG);
mButton.setEnabled(false);
}
@Override
protectedDialog onCreateDialog(int id) {
switch(id) {
casePROGRESSDIALOG:
mDlg= new ProgressDialog(this);
mDlg.setMessage("数据更新请稍等");
mDlg.setButton(ProgressDialog.BUTTON_NEGATIVE,"取消", this);
returnmDlg;
}
returnnull;
}
@Override
publicvoid onClick(DialogInterface dialog, int which) {
//TODO Auto-generated method stub
switch(which) {
caseProgressDialog.BUTTON_NEGATIVE:
mDlg.cancel();
if(mTask != null) {
mTask.cancel(true);
}
mButton.setEnabled(true);
break;
}
}
}
//提供静态数据类:
Data.java
package com.wy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import android.util.Pair;
public class Data {
privatestatic final int pageSize = 10;
privatestatic List<String> mData = new ArrayList<String>();
privatestatic final String[] mStrings = {"1 AbbayedeBelloc",
"2 AbbayeduMontdesCats",
"3 Abertam",
"4 Abondance",
"5 Ackawi",
"6 Acorn",
"7 Adelost",
"8 AffideliceauChablis",
"9 Afuega'lPitu",
"10Airag",
"11Airedale",
"12AisyCendre",
"13AllgauerEmmentaler",
"14Alverca",
"15Ambert",
"16AmericanCheese",
"17AmiduChambertin",
"18AnejoEnchilado",
"19AnneauduVic-Bilh",
"20Anthoriro",
"21Appenzell",
"654ZanettiParmigianoReggiano"};
static{
mData= Arrays.asList(mStrings);
}
publicstatic Pair<Boolean, List<String>> getRows(int page) {
System.out.println("getRows()"+ page );
if(page == 1) {
booleanhasMore = mStrings.length > pageSize;
returnnew Pair<Boolean, List<String>>(hasMore, mData.subList(0,
pageSize));
}else {
for(int i = 0; i < 5; i++) {
try{
Thread.sleep(1000);
}catch (InterruptedException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
booleanhasMore = mStrings.length > pageSize * page;
intstart = (page - 1) * pageSize;
returnnew Pair<Boolean, List<String>>(hasMore, mData.subList(
start,Math.min(start + pageSize, mStrings.length)));
}
}
}