我们在项目中很多时候会用到异步任务,首先异步任务是个抽象的类,我们需要继承AsyncTask类,AsyncTask<Params, Progress, Result>中的三个参数Params是我们实现AsyncTask类传递的参数类型Progress是我们后台执行任务的进度,Result是我们执行完任务的返回值(doInBackground()的返回值类型)。如果没有使用到可以用Void,如AsyncTask<Void, Void, Void>。接下来会实现doInBackground(Params... params)方法,在这个方法里我们就可以把耗时的操作,但是在这个方法里不能更新UI。所有我们要想更新UI就要实现onPostExecute(Result result)这个方法中的result值就是doInBackground()的返回的值,这样以来我们就可以与UI进行交互了。许多时候我们会给耗时的操作弹一个进度对话框或者是提示对话框之类的窗体,这样我们就会用到onPreExecute()方法。在这个方法里我们就可以创建对话框,如果是进度对话框就会跟着耗时操作走,迟到耗时操作走完对话框才关闭。这样怎么才能监测到进度呢?我们就要使用到onProgressUpdate(Integer... values)方法,在这个方法中设置进度,这个方法中的values值是怎么来的呢,我们要使用publishProgress(Integer)方法在doInBackground()中获得进度值,这样我们就可以在onProgressUpdate方法中progressDialog.setProgress(values[0]),来更新进度。等任务执行完以后我们就在onPostExecute()方法中关闭对话框。
代码如下:
class BackupTask extends AsyncTask<String, Integer, Integer> {
private NotesDatabaseHelper mHelper = new NotesDatabaseHelper(
getBaseContext());
// 创建ProgressDialog对象
ProgressDialog progressDialog = new ProgressDialog(BackupActivity.this);
@Override
protected void onPreExecute() {
super.onPreExecute();
count = 0;
// 设置进度条风格,风格为长形
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
// 设置ProgressDialog 标题
progressDialog.setTitle(getString(R.string.backup_hint));
// 设置ProgressDialog 提示信息
progressDialog.setMessage(getString(R.string.backup_being_backup));
// 设置ProgressDialog 标题图标
progressDialog.setIcon(R.drawable.folder);
// 设置ProgressDialog 进度条进度
progressDialog.setProgress(100);
// 设置ProgressDialog 的进度条是否不明确
progressDialog.setIndeterminate(false);
// 设置ProgressDialog 是否可以按退回按键取消
progressDialog.setCancelable(true);
// 设置点击屏幕ProgressDialog不消失
progressDialog.setCanceledOnTouchOutside(false);
// 让ProgressDialog显示
progressDialog.show();
}
@Override
protected Integer doInBackground(String... arg0) {
try {
String path = mSdPath + "/" + "Notes/Backups";
SQLiteDatabase db = mHelper.getWritableDatabase();
this.publishProgress(0);
Thread.sleep(500);
UtilData.backupsData(db);
this.publishProgress(20);
Thread.sleep(500);
UtilData.backupsNote(db);
this.publishProgress(50);
Thread.sleep(500);
File file = new File(path);
// 判断文件夹是否存在
if (file.exists() && file.isDirectory()) {// 存在
try {
ZipUtils.ZipFolder(path, mSdPath + "/"
+ "Notes/Backup.zip");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.publishProgress(100);
Thread.sleep(500);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if (progressDialog != null) {
progressDialog.setProgress(values[0]);
}
}
@Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
if (progressDialog != null) {
progressDialog.dismiss();
}
}
}
上面的代码我们可以看出进度是我们自己设置的,单耗时的操作比较多有不好监测的时候我们可以在每个方法执行完后自己设置一个进度值,等全部执行完 publishProgress(100)就行了。
class saveVideoTask extends AsyncTask<String, Integer, Boolean>{
// 创建ProgressDialog对象
ProgressDialog progressDialog = new ProgressDialog(EditActivity.this);
//后台接口
TransformationUtil util = new TransformationUtil();
VideoEditor videoEditor = util.createProject(getApplicationContext(), entity.getName());
boolean cancel = true;
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setTitle(getString(R.string.save));
progressDialog.setMessage(getString(R.string.save_being));
progressDialog.setProgress(100);
progressDialog.setIndeterminate(false);
progressDialog.setCancelable(false);
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
cancel = false;
util.cancelExport();
}
});
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.show();
}
@Override
protected Boolean doInBackground(String... params) {
//导出保存
boolean isSucesessed = false;
try {
util.exportMovie(getApplicationContext(), mApp.source, new ExportListener() {
@Override
public void onProgress(VideoEditor videoEditor, String filename,
int progress) {
publishProgress(progress);
}
});
isSucesessed = true;
} catch (Exception e) {
e.printStackTrace();
}
return isSucesessed && cancel;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if (progressDialog != null) {
progressDialog.setProgress(values[0]);
}
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
progressDialog.dismiss();
if (result ) {
// 清空数据
mApp.source.saveProject(getApplicationContext());
mApp.source.clearProject();
// 退出
Intent intent = new Intent();
intent.setClass(EditActivity.this, ShareActivity.class);
intent.putExtra("savePath",entity.getPath());
startActivity(intent);
finish();
}
}
}
上面的代码就是能够清楚的知道进度因为在util.exportMovie()方法中有明确的进度返回值。
下面是一个简单的Demo让大家能看的更清楚。
public class MainActivity extends Activity
{
private Button buton;
private TextView text;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
buton = (Button) findViewById(R.id.start_btn);
text = (TextView) findViewById(R.id.content);
buton.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
update();
}
});
}
private void update(){
new UpdateTextTask.execute();
}
class UpdateTextTask extends AsyncTask<Void,Integer,Integer>{
private Context context;
UpdateTextTask(Context context) {
this.context = context;
}
/**
* 运行在UI线程中,在调用doInBackground()之前执行
*/
@Override
protected void onPreExecute() {
}
/**
* 后台运行的方法,可以运行非UI线程,可以执行耗时的方法
*/
@Override
protected Integer doInBackground(Void... params) {
int i=0;
while(i<10){
i++;
publishProgress(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
return null;
}
/**
* 运行在ui线程中,在doInBackground()执行完毕后执行
*/
@Override
protected void onPostExecute(Integer integer) {
}
/**
* 在publishProgress()被调用以后执行,publishProgress()用于更新进度
*/
@Override
protected void onProgressUpdate(Integer... values) {
tv.setText(""+values[0]);
}
}
}
有时候在使用异步任务时我们需要传递一些参数便于我们在doInBackground()方法中使用。代码如下:
//这里我们传递了二个参数
MyTask myTask = new MyTask();
myTask.execute(cunt, name);
protected void doInBackground(Object... params) {
// 这里我们接收二个参数
//第一个参数
long cunt = (Long) params[0];
//第二个参数
String name = (String) params[1];
}
希望对大家有所帮助。