一.什么是异步操作
异步操作是指把消耗时间的操作放在另一个线程内执行,变成两个线程独立并行执行的状态。通常涉及网络的操作大多数放在异步任务中。
二.异步任务AsyncTask
1.建立异步任务
public class FirstAsyncTask extends AsyncTask<Integer,Integer,String>{ //当然,这里的泛型类型根据需要可以是任何类型。
//参数1:定义的是doInBackground方法中接收参数的类型。
//参数2:定义onProgressUpdate方法中接收参数的类型。
//参数3:定义的是doInBackground的返回值类型以及onPostExcute方法接收参数的类型。
@override
protected void onPreExcute(){ //在excute()方法调用后首先执行。它是执行在UI线程中的,即主线程,所以在该方法内部可以对
......//UI线程中的控件进行操作。
}
@override
protected String doInBackground(Integer... param){ //在这个函数里的操作会在后台执行,即其内的代码在另一个线程中执行,不
//会影响当前线程。但该方法在异步线程中而非UI线程中,因此不能对UI中的控件
//进行操作。
//参数是变长的,可以是一个,也可以是多个。参数由主线程的excute()方法传入
...... //在这里写入需要独立执行的操作
publishProgress(int i); //用于发布更新方法,会触发onProgressUpdate方法
return str; //这个返回值返回给onPostExcute。
}
@override
protected void onProgressUpdate(Integer... values){ //这个方法也是在UI线程中执行的,所以在该方法内部可以对UI线程中的控
//件进行操作。该方法用于在异步任务的执行过程中,对用户进行提示,例
//如控制进度条等。
......
}
@override
protected void onPostExcute(String str){ //在doInBackground()方法执行后执行。它是执行在UI线程中的,即主线程,所以在该
...... //方法内部可以对UI线程中的控件进行操作。
}
}
2.在主线程中执行异步任务
FirstAsyncTask asyncTask=new FirstAsyncTask ();
asyncTask.excute(); //注意,这里的excute如果有值,比如excute(1000),则表示的是doInBackground的参数,含有一个值,则是
//doInBackground的第0个参数,含有两个值,则是doInBackground的第1个参数,如此类推。
AsyncTask与Handler的对比和具体的描述:
异步的轻量级实现;
AsynceTask简述:
1.功能类似于Handler,都是为了防止UI线程操作阻塞而衍生而来。
2.AsyncTask是Handler的一个轻量级实现,模型类似于IntentService于Service。都是为了更加方便操作。(因为一般的异步,我们都是开启一个子线程或是匿名线程,缺点就是样的实现对于线程的操作,控制是十分困难)
3.阐述下Handler,一般我们就认为Handler既一个Android消息处理器。默认情况下,他只接受当前线程的消息实例。
但是,当在一个多线程,比如子线程数据处理后更新Ui线程,此时只要存在Handler的指针,简单的说就是实例对象时,
消息的收发处理就能执行在不同的进程中了,这个也是我们常用到的异步处理手法。
4.从源代码中看AsyncTask类中有 线程池,同样也实例化了一个Handler对象。
说白了,AsyncTask只是对以上我们自己用handler,thread实现的异步做了一个很好的封装,使用到线程池对于线程的销毁和创建开销大大减小
综合了下:AsyncTask的异步处理相对于传统的handler+Thread组合,减少程序中线程过多开销过大。操作和管理更加方便。
AsyncTask的是实现:
和所有网上说的一样,该对象必须在UiThread中实例化,然后执行execute方法。
copy下:AsyncTask定义了三种泛型类型 Params,Progress和Result。
•Params 启动任务执行的输入参数,比如HTTP请求的URL。
•Progress 后台任务执行的百分比。
•Result 后台执行任务最终返回的结果,比如String。
AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,开发者需要实现一个或几个方法。在任务的执行过程中,这些方法被自动调用。
onPreExecute(), 该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。
doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
onProgressUpdate(Progress...),在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread.
使用AsyncTask类,以下是几条必须遵守的准则:
1) Task的实例必须在UI thread中创建
2) execute方法必须在UI thread中调用
3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法
4) 该task只能被执行一次,否则多次调用时将会出现异常
下面以一张图来说明异步操作的过程:
从图示中可以看出,只有doInBackground工作在另外一个线程中,所以可以在其他的回调方法当中实现对UI的更新。
下面以一个具体的实例介绍AsyncTask
这个例子实现的是在异步线程中更新进度条的进度:
实现这个例子需要三个类:
1.模拟耗时操作的类:
public class netOperator {
public void operator(){
try {
Thread.sleep(1500);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
2.实现异步操作的类:
//生成该类的对象,并调用其execute方法之后
//1.首先执行的是onPreExecute方法
//2.其次执行的是doInBackground方法
/*
* AsyncTask<Integer, Integer, String>三个参数的介绍
* 1.Integer--标志了doInBackground的参数类型
* 2.Integer--标志了onProgressUpdate的参数类型
* 3.String--标志了doInBackground的返回类型和onPostExecute的参数类型
*/
public class ProgressBarAsyncTask extends AsyncTask<Integer, Integer, String>{
private TextView textView;
private ProgressBar progressBar;
private Button button;
public ProgressBarAsyncTask(TextView textView,ProgressBar progressBar,Button button){
this.textView=textView;
this.progressBar=progressBar;
this.button=button;
}
//该方法并不运行在UI线程当中,所以在改方法中不能更新UI里面的东西,例如对其中的控件进行设置
@Override
protected String doInBackground(Integer... params) {
// TODO Auto-generated method stub
netOperator netOperator=new netOperator();
int i=0;
for(i=10;i<=100;i+=10){
netOperator.operator();
//用于发布更新
publishProgress(i);
// This method can be invoked from doInBackground(Params...) to publish updates
// on the UI thread while the background computation is still running.
// Each call to this method will trigger the execution of onProgressUpdate(Progress...)
// on the UI thread. onProgressUpdate(Progress...) will note be called
// if the task has been canceled.
}
return i+params[0]+"";
}
//该方法是在doInBackground方法执行完毕之后执行,且运行在UI线程当中,其中的参数result就是doInBackground的返回值
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
textView.setText("异步操作执行结束"+result);
button.setText("异步测试结束!!!");
}
//该方法运行在UI线程当中,主要是在异步操作之前所做的一些准备工作
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
textView.setText("开始执行异步操作。。。");
}
//在doInBackground方法执行过程中,每次调用publishProgress方法,都会触发该方法的执行
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
int value=values[0];
progressBar.setProgress(value);
}
}
3.主函数的实现:
public class MainActivity extends Activity {
private TextView textView;
private ProgressBar progressBar;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.textview);
progressBar=(ProgressBar)findViewById(R.id.progressbar);
button=(Button)findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
ProgressBarAsyncTask pTask=new ProgressBarAsyncTask(textView, progressBar,button);
pTask.execute(1000);
button.setText("测试中。。。");
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
分享到:
相关推荐
安卓开发-android录音上传到服务器,上传使用AsyncTask异步任务.zip
NULL 博文链接:https://aking86.iteye.com/blog/1329089
android异步任务加载组件,是我们常用的。该demo详细的介绍了,如何通过异步加载数据,很适合处学者的开发。
Android 应用开发源码 参考与学习使用
Android应用源码开发Demo,主要用于毕业设计学习。
因为,UI线程主要是用来更新界面UI,如果一次进行太多的任务处理,并且这些任务需要相当的时间来完成,就会造成UI线程堵塞,结果可能是应用无响应(Android4.0以后,谷歌已经禁止在UI线程中进行“耗时操作”),这样的...
android较轻级异步任务的一点理解。
Android应用源码开发Demo,主要用于毕业设计学习。
减少了许多重复的工作,是一个Google的AsyncTask的精简版(使用Google的AsyncTask,内部开销比较大,不适合简单开发,对于比较负责或者要求多线程异步任务的时候比较适合使用Google的AsyncTask)
为什么要用异步任务? 在Android中只有在主线程才能对ui进行更新操作,而其它线程不能直接对ui进行操作 android本身是一个多线程的操作系统,我们不能把所有的操作都放在主线程中操作 ,比如一些耗时操作。如果放在...
Android为了降低这个开发难度 提供了AsyncTask AsyncTask就是一个封装过的后台任务类 顾名思义就是异步任务 AsyncTask直接继承于Object类 位置为android os AsyncTask 要使用AsyncTask工作我们要提供三个泛型参数 ...
Android AsyncTask实现异步处理任务的方法详解 在开发Android应用时必须遵守单线程模型的原则:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。 Android 单线程模型概念详解://...
Android的日常开发中,经常需要处理异步任务,系统提供的Handler和Asynctask实在不方便,一些开源的第三方库由于过于庞大和复杂,例如RxJava,虽然很方便,但RxJava在团队中不容易推广,所以实现了一个简洁、方便、...
在Android中实现异步任务机制有两种方式,Handler和AsyncTask。 Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更新,这种方式对于整个过程的控制比较精细,...
这里说有设计思想是我根据查看Android源代码提炼出来的代码逻辑,所以不会跟Google工程师的原始设计思想100%符合(也有可能是0%),但是本文一定可以帮助你理解AsyncTask,也可能有一些你以前没有发现的内容。...
AsyncTask,顾名思义,异步任务。说到异步,最简单的理解就是不同步。再复杂一点理解,就得举例子了。 假设我要去火车站买票,刚到火车站我突然发现我忘了带身份证。怎么办?怎么办! 想办法,想办法!我想我应该找...
|--异步任务AsyncTask的用法 |--异步任务的自定义 |--快捷方式增删查 |--手势识别器GestureDetector的用法 |--拍照之调用系统相机并显示及保存 |--拨打电话 |--按健之长按menu事件屏蔽 |--按健监听按返回健回桌面 |-...
使用AsyncTask异步任务; 使用runOnUiThread(action)方法; 使用Handler的post(Runnabel r)方法; 下面分别使用四种方式来更新一个TextView。 1.使用Handler消息传递机制 package ...
15.1 AsyncTask异步任务介绍一 15.2 AsyTask异步任务介绍二 15.3 Handler和Message(一) 15.4 Handler和Message(二) 15.5 Handler和Message(三) 15.6 Handler和Looper 15.7 Handler综合练习(图文混排)