Anroid提供了一个简单的异步任务类AsyncTask,可以自动开启新线程并且更新UI。
使用起来也非常简单,重写其中的几个方法即可。
AsyncTask的基本用法
首先新建一个类继承AsyncTask,需要指定三个泛型参数。
class MyAsyncTask extends AsyncTask <Void, Integer, String>{
}
- parmas
第一个参数parmas的类型是执行Async时传入的参数,这里我们选择不传入参数。 - progress
第二个参数progress可以显示AsyncTask任务的进度,这里我们选择Integer类型。 - result
第三个参数是后台任务完成后对结果的返回,这里选择String类型。
重写主要的方法
AsyncTask必须重写的方法是doInBackGround(),另外还有几个方法也经常重写:
- onPreExecute()
这个方法是AsyncTask后台任务开始执行前的初始化操作,比如显示进度条等。
@Override
protected void onPreExecute()
//初始化
}
- doInBackGround(Void... parmas)
这个方法就是后台任务,其中所有的代码会在子线程中进行,一般耗时操作写在这里。
方法的参数是泛型参数1,即parmas。
这个方法的返回值就是第三个泛型参数result,返回值通会传到onPostExecute(),进行UI更新等操作。
另外,doInBackGround()方法里可以使用publishProgress()方法传递后台任务进度。
@Override
protected String doInBackGround(Void... parmas) {
//后台任务
...
//传递后台任务的进度值
pubishProgress(10);
...
return "string";
}
- onProgressUpdata(integer... progress)
publishProgress()方法被调用后,这个方法很快就会运行。
这个方法可以将进度值在UI上更新出来。
@Override
protected void onProgressUpdata(integer... progress) {
//在UI更新后台任务的进度,
setMessage(progress);//这是个虚构方法
}
- onPostExecute()
这个方法接收doInBackGround的结果,更新UI。
@Override
protected void onPostExecute(String result) {
//更新UI
setText(result);//这是个虚构方法
}
调用AsyncTask
上边重写的方法不可以直接调用,调用AsyncTask需要用方法execute(parmas).
new MyAsyncTask().execute();//MyAsynvTask的parmas泛型是Void,这里不需要参数。
需要注意的是AsynvTask类的每个实例只能执行一次,因此每次执行都需要用new生成个新实例。
完整的代码示例
结合之前的HttpURLConnection类的用法,写了一段代码。
主活动有1个button和1个textView实例。
点击button后将指定网址(范例是baidu)的reponse显示在textView里。
由于HTTP请求耗时,因此写在AsyncTask里。
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button button;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button)findViewById(R.id.button);
textView = (TextView)findViewById(R.id.textView);
button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
//HTTP请求
new HttpURLConnectAsyncTask().execute("http://www.baidu.com");
break;
default:
break;
}
}
class HttpURLConnectAsyncTask extends AsyncTask<String, Integer, String> {
@Override
protected void onPreExecute() {
//初始化
super.onPreExecute();
}
@Override
protected String doInBackground(String... parmas) {
//自动开启线程,耗时任务放在这里
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
//使用HttpURLConnecttion发送HTTP请求
URL url = new URL(parmas);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
InputStream inputStream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder sBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sBuilder.append(line);
}
return sBuilder.toString();
} catch (Exception e) {
e.printStackTrace();
return "Error!";
} finally {
if (reader != null) {
try {
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (connection != null) {
connection.disconnect();
}
}
}
@Override
protected void onProgressUpdate(Integer... values) {
//更新进度,本范例没有写>_<
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(String s) {
//更新textView
textView.setText(s);
}
}
}