异步任务的总结



        我们在项目中很多时候会用到异步任务,首先异步任务是个抽象的类,我们需要继承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];
	}

希望对大家有所帮助。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值