android异步线程

多线程异步执行,带有进度条显示 例子:  http://www.cnblogs.com/xiaoluo501395377/p/3430542.html 
http://vaero.blog.51cto.com/4350852/782595 (里面的例子挺详细)

当执行比较耗费时间的任务时,一般为了提高用户体验,会将比较耗时的功能(一般这些功能是重复某一操作直到某一条件失效时才完成该功能),放在后台线程里,同时一般在UI线程使用控件(progressBar...)来显示线程执行的进度,这样就出现了异步线程。android内部自己封装了一种异步线程类  AsyncTask 。

一般过程:继承 AsyncTask 类;重写AsyncTask 类的方法。

常用重写的方法:
1. onPreExecute(),该方法将在执行实际的后台操作前被UI thread调用,是在主线程里运行的。做一些准备工作,如在界面上显示一个进度条,设置进度条 的初始值。
2. doInBackground(Params...),将在AsyncTask 的实例对象调用onPreExecute方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
3. onProgressUpdate(Progress...),在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,这个方法是运行在主线程里的,因此可以在此方法里对UI线程中存在的控件进行修改,例如修改进度条的值   progressdialog.setprogress(  values[0])。

4. onPostExecute(Result),在耗时的后台线程执行完成后,onPostExecute方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread。例如当完成文件复制后,需要在listView里重新刷新,显示当前所有的文件,这时就可以在此方法中刷新listView显示的内容。

使用准则
         1) Task的实例必须在UI thread中创建
         2) execute方法必须在UI thread中调用
         3) 不要手动的调用onPreExecute(), onPostExecute(Result),
doInBackground(Params...), onProgressUpdate(Progress...)这几个方法
         4) 该task只能被执行一次,否则多次调用时将会出现异常


当需要运行用户随时取消当前任务在后台的线程时,可以在 progressDialog中添加一个button ,并添加该button点击时触发的事件,方法如下:

(在UI线程里写的代码,参考)
progressDialog1.setTitle("删除");
progressDialog1.setIcon(R.drawable.del);
progressDialog1.setMessage("正在删除,请稍后......");
// 设置setCancelable(false); 表示我们不能取消这个弹出框,等下载完成之后再让弹出框消失
progressDialog1.setCancelable(false);
// 设置ProgressDialog样式为水平的样式
progressDialog1
.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog1.setButton("取消", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
progressDialog1.dismiss();     //进度对话框消失
msyncdel.cancel(true); /*msyncdel是android异步线程类实例对象,使后台线程退出,在后台的线程执行需要随时检查用户是否已经取消后台线程  通过  isCanceled方法来检测,返回TRUE 说明已经取消后台线程,FALSE说明后台线程还在运行*/
}
});

(在后台异步线程里执行的代码:参考)
for (int i = 0; i < tmpNum; i++) {

if (!isCancelled()) {    //每次循环都检查UI线程是否取消了后台异步线程
filePath = selectFilePath.get(i);
try {
fileOpera.deleteAll(new File(selectFilePath.get(i)));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

int progress = (int) (i / (double) (tmpNum)) * 100; //计算进度条的值,已经执行的占总量的百分比
publishProgress(progress);
}

应用场景:用户选择了要复制的文件或者文件夹,把它们的路径已经存进 了一个arrayList中,点击  粘贴  功能按钮时,这时就需要后台异步线程把文件复制到目标文件夹,同时在UI线程里面用进度条来显示任务的执行进度。
progressDialog1.setTitle("粘贴"); 
progressDialog1.setIcon(R.drawable.paste);
progressDialog1.setMessage("正在粘贴文件");
// 设置setCancelable(false); 表示我们不能取消这个弹出框,等下载完成之后再让弹出框消失
progressDialog1.setCancelable(false);
// 设置ProgressDialog样式为水平的样式
progressDialog1.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog1.setMax(selectFilePath.size());
final mSyncPaste msyncpaste = new mSyncPaste();   //声明 android异步线程类的对象

progressDialog1.setButton("取消", new OnClickListener() { //进度条对话框添加取消按钮 和 按钮监听事件
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
progressDialog1.dismiss();  //让进度条对话框消失
msyncpaste.cancel(true);  //取消后台线程

}
});
msyncpaste.execute(1000);

重写android异步线程类的对象:
/* 异步执行粘贴操作线程 */
private class mSyncPaste extends AsyncTask<Integer, Integer, Boolean> {

String currentDirectory; // 要粘贴的文件所在的文件夹target路径
String newFilePath;// 粘贴后形成的新的文件的路径
String srcFilePath;

@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
System.out.println("\n\n 开始异步执行粘贴操作线程。");
progressDialog1.setProgress(0);
progressDialog1.show();
}

@Override
protected void onPostExecute(Boolean result) {
// TODO Auto-generated method stub

if (currIndex == 0) {
openDirctory(new File(directoryPath_Local), listView_Local,
false, false);
} else {
openDirctory(new File(directoryPath_SD), listView_SD, false,
false);
}
selectFileName.clear();
selectFilePath.clear();
System.out.println("\n\n 结束异步执行粘贴操作线程。");
progressDialog1.dismiss();
}

@Override
protected void onCancelled() {
// TODO Auto-generated method stub
if (currIndex == 0) {
openDirctory(new File(directoryPath_Local), listView_Local,
false, false);
} else {
openDirctory(new File(directoryPath_SD), listView_SD, false,
false);
}
selectFileName.clear();
selectFilePath.clear();
System.out.println("\n\n 强迫结束异步执行粘贴操作线程。");
super.onCancelled();
}

@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
progressDialog1.setMessage("正在粘贴文件:" + srcFilePath);
progressDialog1.setProgress(values[0]);
}

@Override
protected Boolean doInBackground(Integer... params) {
// TODO Auto-generated method stub
if (currIndex == 0) {
currentDirectory = directoryPath_Local;
} else {
currentDirectory = directoryPath_SD;
}
int tmpNum = selectFilePath.size();
// 逐项 复制文件到 target路径
for (int i = 0; i < tmpNum; i++) {
newFilePath = currentDirectory + "/" + selectFileName.get(i);
srcFilePath = selectFilePath.get(i);
final File srcFile = new File(srcFilePath);
final File newFile = new File(newFilePath);
System.out.println("\n 文件源路径为 :" + srcFilePath);
System.out.println("\n 文件target路径为 :" + newFilePath);

if (!isCancelled()) { //每次循环复制文件时先判断线程是否已经被取消
fileOpera.copyFile(srcFile, newFile); // 目标文件不存在时

int progress = (int) (((i + 1) / (double) tmpNum) * 100);
publishProgress(i);
}
}

if (isClickCut) // 如果执行的是剪切操作 就在粘贴操作后 删除源文件 再次把 变量
{
// 逐项 刪除文件
for (int i = 0; i < tmpNum; i++) {

try {
fileOpera.deleteAll(new File(selectFilePath.get(i)));

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
isClickCut = false;
}
return null;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值