【安卓筆記】AsyncTask
阿新 • • 發佈:2019-01-24
public abstract class AsyncTask<Params, Progress, Result>
泛型引數:
Params:執行後臺任務所需的引數。比如如果你是網路操作的話,maybe需要傳入一個uri
Progress:後臺任務執行的進度。比如下載進度,通常是一個Integer,這個引數會被onProgressUpdate呼叫,然後去更新UI,比如ProgressBar或者progressDialog。
Result:後臺任務執行所返回的結果。比如你想下載一張圖片,那可以將Result指定為Bitmap
如果你的AsyncTask不需要某個引數,可以直接指定為Void.- Task的例項必須在UI 執行緒中建立;
- execute方法必須在UI 執行緒中呼叫;
- 不要手動的呼叫onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)這幾個方法;
- 該task只能被執行一次,多次呼叫execute時將會出現異常;
- 不要在doInBackground方法中更新UI。
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
if (mStatus != Status.PENDING) {
switch (mStatus) {
case RUNNING:
throw new IllegalStateException("Cannot execute task:"
+ " the task is already running.");
case FINISHED:
throw new IllegalStateException("Cannot execute task:"
+ " the task has already been executed "
+ "(a task can be executed only once)");
}
}
... ...
所以你希望多次呼叫的話,只能new多個AsyncTask了,像這樣:new AsyncTask(){}.execute(..);
使用步驟:
1.繼承AsyncTask類,在doInbackground方法中寫好邏輯。
2.呼叫execute方法。
像這樣:
new AsyncTask<Void, Void, Void>() {
protected Void doInBackground(Void... params)
{
//TODO handle task
return null;
}
@Override
protected void onPostExecute(Void result)
{
//TODO update UI
}
}.execute(null);
以下載網路圖片為例:
佈局:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/iv_show"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1000" />
<Button
android:id="@+id/but_down"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="下載" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<ProgressBar
android:id="@+id/pb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_gravity="center" />
<TextView
android:id="@+id/tv_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="#fff"
android:visibility="gone"
android:text="下載進度:"
android:textColor="#000" />
</LinearLayout>
</FrameLayout>
activity:package com.example.asynctaskdemo4;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener
{
private static final String PATH = "http://10.46.191.198:8080/demo.bmp";
private Button but_down = null;
private ImageView iv_show = null;
private TextView tv_progress = null;
private ProgressBar pb = null;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
but_down = (Button) findViewById(R.id.but_down);
iv_show = (ImageView) findViewById(R.id.iv_show);
tv_progress = (TextView) findViewById(R.id.tv_progress);
pb = (ProgressBar) findViewById(R.id.pb);
but_down.setOnClickListener(this);
}
@Override
public void onClick(View v)
{
if (R.id.but_down == v.getId())
{
new DownloadImageTask().execute(PATH);
}
}
private class DownloadImageTask extends AsyncTask<String, Integer, Bitmap>
{
@Override
protected void onPostExecute(Bitmap result)
{
if (result != null)
{
tv_progress.setVisibility(View.GONE);
pb.setVisibility(View.GONE);
iv_show.setImageBitmap(result);
} else
{
tv_progress.setVisibility(View.GONE);
pb.setVisibility(View.GONE);
Toast.makeText(MainActivity.this,"下載失敗",0).show();
}
}
@Override
protected Bitmap doInBackground(String... params)
{
String path = params[0];
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(path);
try
{
HttpResponse resp = client.execute(get);
if(resp.getStatusLine().getStatusCode() == 200)
{
HttpEntity entity = resp.getEntity();
if(entity == null)
{
return null;
}
long total_length = entity.getContentLength();//獲取檔案總長
InputStream is = entity.getContent();
ByteArrayOutputStream bous = new ByteArrayOutputStream();
int len = 0;
byte[] buf = new byte[1024];
int current_len = 0;
int progress = 0;//當前下載進度
while((len = is.read(buf))!= -1)
{
current_len+=len;
bous.write(buf, 0, len);
//注意progress的寫法哦
progress = (int) ((current_len/(float)total_length)*100);
this.publishProgress(progress);
}
is.close();
byte[] data = bous.toByteArray();
Options opts = new Options();
opts.inSampleSize = 2;//簡單起見直接指定縮放比例
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, opts);
return bitmap;
}
} catch (Exception e)
{
e.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values)
{
tv_progress.setText("下載進度:"+values[0]);
}
@Override
protected void onPreExecute()
{
tv_progress.setVisibility(View.VISIBLE);
pb.setVisibility(View.VISIBLE);
}
}
}
顯示效果: