异步任务的总结

来源:互联网 发布:《网络黑白》txt下载 编辑:程序博客网 时间:2024/05/23 00:25


        我们在项目中很多时候会用到异步任务,首先异步任务是个抽象的类,我们需要继承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);@Overrideprotected 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();}@Overrideprotected 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 blocke.printStackTrace();}}this.publishProgress(100);Thread.sleep(500);} catch (InterruptedException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}return null;}@Overrideprotected void onProgressUpdate(Integer... values) {super.onProgressUpdate(values);if (progressDialog != null) {progressDialog.setProgress(values[0]);}}@Overrideprotected 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;@Overrideprotected 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() {@Overridepublic void onClick(DialogInterface dialog, int which) {cancel = false;util.cancelExport();}});progressDialog.setCanceledOnTouchOutside(false);progressDialog.show();}@Overrideprotected Boolean doInBackground(String... params) {//导出保存boolean isSucesessed = false;try {util.exportMovie(getApplicationContext(), mApp.source, new ExportListener() {@Overridepublic void onProgress(VideoEditor videoEditor, String filename,int progress) {publishProgress(progress);}});isSucesessed = true;} catch (Exception e) {e.printStackTrace();}return isSucesessed && cancel;}@Overrideprotected void onProgressUpdate(Integer... values) {super.onProgressUpdate(values);if (progressDialog != null) {progressDialog.setProgress(values[0]);}}@Overrideprotected 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];}

希望对大家有所帮助。




0 0