1、AsyncTask是Android为了解决UI主线程不阻塞的问题而提供的一个较Handler更轻量级的一个异步类。
先来看一个不使用异步处理开启线程的例子:
package com.tang.Javen;
import android.app.Activity;
public class MainActivity extends Activity {
private Button threadBtn, getLogBtn;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
threadBtn = (Button)findViewById(R.id.button1);
getLogBtn = (Button)findViewById(R.id.button2);
threadBtn.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
ThreadOperator operator = new ThreadOperator();
operator.operate();
}
});
getLogBtn.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Log.d("Javen","获取打印信息");
}
});
}
}
package com.tang.Javen;
public class ThreadOperator
{
public void operate()
{
try
{
Thread.sleep(8*1000);
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这里我们在主线程中去new一个ThreadOperator类,然后在这个类中去让线程睡眠8秒中,而这里的线程就是指的主线程。
当点击开启线程这个Button时,然后在点击获取打印的Button,就可以看到
系统提示没有响应,这就是因为在主线程中线程阻塞时间太长的原因,android一般主线程阻塞5秒之后,系统就会提示无响应。所有我们最好的办法就是把比较耗时的操作放到一个异步类中去,让这些比较耗时的操作不阻塞我们的主线程。
2、新建一个类继承AsyncTask,然后在这里让线程休眠
package com.tang.Javen;
import android.os.AsyncTask;
public class FristAysnTask extends AsyncTask<Void, Void, Void>
{
@Override
protected Void doInBackground(Void... params)
{
ThreadOperator operator = new ThreadOperator();
operator.operate();
return null;
}
}
在MainActivity中修改代码
threadBtn.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
// ThreadOperator operator = new ThreadOperator();
// operator.operate();
Frist<span class="KSFIND_CLASS_SELECT" id="0KSFindDIV">AysncTask </span><span class="KSFIND_CLASS" id="1KSFindDIV">aysncTask </span>= new FristAysncTask();
aysncTask.execute();
}
});
这个我们就把耗时操作放到了异步线程中去了
这样就不会出现无响应的问题了,同时打印信息也可以很快就打印出来了.
3、使用AsyncTask来实现如下图界面的功能
package com.tang.Javen;
import android.app.Activity;
public class MainActivity extends Activity {
private Button asyncTaskBtn;
private TextView textView;
private ProgressBar progressBar;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
aysncTaskBtn = (Button)findViewById(R.id.button1);
textView = (TextView)findViewById(R.id.text);
progressBar = (ProgressBar)findViewById(R.id.progressBar1);
asyncTaskBtn.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
/*ThreadOperator operator = new ThreadOperator();
operator.operate();*/
Frist<span class="KSFIND_CLASS" id="2KSFindDIV">AsyncTask </span><span class="KSFIND_CLASS" id="3KSFindDIV">asyncTask </span>= new FristAsyncTask(textView, progressBar);
asyncTask.execute(1000);
}
});
}
}
这里asyncTask.execute(1000)的1000会传递到AsyncTask类中的doInBackground函数中当我参数
package com.tang.Javen;
import android.os.AsyncTask;
import android.widget.ProgressBar;
import android.widget.TextView;
public class Frist<span class="KSFIND_CLASS" id="4KSFindDIV">AsyncTask </span>extends AsyncTask<Integer, Integer, String>
{
private TextView textView = null;
private ProgressBar progressBar = null;
public FristAsyncTask(TextView textView, ProgressBar progressBar)
{
super();
this.textView = textView;
this.progressBar = progressBar;
}
/**
* 在执行完onPreExecute函数后,就正式进入到异步操作了,开启另外一个线程
* 在AysncTask类中有三个参数,第一个参数就是指的doInBackground中要传入的参数
* 这个的参数,是从MainActivity中的asyncTask.execute(1000)传过来的
* 其中Integer...代表这个参数是一个数组,也可以这样传asyncTask.execute(1000,2000),则params[0] == 1000, params[1]== 2000
* doInBackground的返回值类型则是AysncTask中的第三个参数,且这个返回的值最终会传递到onPostExecute()中去
*/
@Override
protected String doInBackground(Integer... params)
{
int i = 0;
ThreadOperator operator = new ThreadOperator();
for(i = 10; i <= 100; i+=10)
{
operator.operate();
/**
* 在doInBackground中调用publishProgress函数,则会调用onProgressUpdate()函数
* 主要用来更新UI主线程中的progressBar的状态
*/
publishProgress(i);
}
return i + params[0].intValue() + "";
}
//最后当异步操作结束后,会调用到onPostExecute函数,且把doInBackground的返回值作为参数传进这个onPostExecute
@Override
protected void onPostExecute(String result)
{
// TODO Auto-generated method stub
super.onPostExecute(result);
textView.setText("<span class="KSFIND_CLASS" id="5KSFindDIV">AysncTask </span>结束"+result);
}
/**
* 当execute一个AsyncTask后首先就会调用这个类的onPreExecute()函数,
* 且这个函数是在UI主线程中执行,所有可以做开启异步操作之前的UI界面更新提示
*/
@Override
protected void onPreExecute()
{
// TODO Auto-generated method stub
super.onPreExecute();
textView.setText("AysncTask异步线程开启");
}
//onProgressUpdate会在调用publishProgress后被调用,且这个函数是在UI主线程中,所有可以用来更新UI界面
@Override
protected void onProgressUpdate(Integer... values)
{
// TODO Auto-generated method stub
super.onProgressUpdate(values);
progressBar.setProgress(values[0]);
}
}
4、AsyncTask的执行过程分析
public class FristAsyncTask extends AsyncTask<Integer, Integer, String>
AsyncTask后带有三个参数(Void代表空)
分别对应如下:
参数一:Integer对应doInBackground中的参数
protected String doInBackground(Integer... params)
参数二:Integer对应onProgressUpdate中的参数
protected void onProgressUpdate(Integer... values)
参数三:String对应doInbackground中的返回值类型和onPostExecute函数中的参数
protected void onPostExecute(String result)
4.1、当我们execute一个AsyncTask时,则会先调用异步类中的onPreExecute函数,这个函数是在UI主线程中执行的
@Override
protected void onPreExecute()
{
// TODO Auto-generated method stub
super.onPreExecute();
textView.setText("AysncTask异步线程开启");
}
我们在这里通过textView来提示异步线程开启
4.2、其次当完成了onpreExecute之后,会调用到doInBackground函数进行真正的异步操作
@Override
protected String doInBackground(Integer... params)
{
int i = 0;
ThreadOperator operator = new ThreadOperator();
for(i = 10; i <= 100; i+=10)
{
operator.operate();
/**
* 在doInBackground中调用publishProgress函数,则会调用onProgressUpdate()函数
* 主要用来更新UI主线程中的progressBar的状态
*/
publishProgress(i);
}
return i + params[0].intValue() + "";
}
在AysncTask类中有三个参数,第一个参数就是指的doInBackground中要传入的参数, 这个的参数,是从MainActivity中的aysncTask.execute(1000)传过来的,其中Integer...代表这个参数是一个数组,也可以这样传aysncTask.execute(1000,2000),则params[0] == 1000, params[1]== 2000,doInBackground的返回值类型则是AysncTask中的第三个参数,且这个返回的值最终会传递到onPostExecute()中去
4.3、 在doInBackground中调用publishProgress函数,则会调用onProgressUpdate()函数, 主要用来更新UI主线程中的progressBar的状态
//onProgressUpdate会在调用publishProgress后被调用,且这个函数是在UI主线程中,所有可以用来更新UI界面
@Override
protected void onProgressUpdate(Integer... values)
{
// TODO Auto-generated method stub
super.onProgressUpdate(values);
progressBar.setProgress(values[0]);
}
4.4、最后当异步操作结束后,会调用到onPostExecute函数,且把doInBackground的返回值作为参数传进这个onPostExecute
@Override
protected void onPostExecute(String result)
{
// TODO Auto-generated method stub
super.onPostExecute(result);
textView.setText("AysncTask 结束"+result);
}
// ThreadOperator operator = new ThreadOperator();
// operator.operate();
如果想注释多行代码可以用Ctrl+shift+/,取消则用Ctrl+shift+\
/*ThreadOperator operator = new ThreadOperator();
operator.operate();*/