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);
}
}
}