您的位置:首页 > 其它

AsyncTask的使用

2016-03-07 19:23 218 查看
加载一张网络图片

MainActivity.java

public class MainActivity extends AppCompatActivity {
private ImageView iv;
private ProgressBar pb;
private Button btn;
public static final String URL = "http://pic3.zhongsou.com/image/38063b6d7defc892894.jpg";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

iv = (ImageView) findViewById(R.id.iv);
pb = (ProgressBar) findViewById(R.id.pb);
btn = (Button) findViewById(R.id.enter_progress);

btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(MainActivity.this,ProgressBarActivity.class);
startActivity(intent);
}
});

new MyAsyncTask().execute(URL);
}

/**
* 方法执行顺序
* onPreExecute()
* doInBackground(String... params),里面回调publishProgress()方法会使用onProgressUpdate(Void... values)
* onPostExecute(Bitmap bitmap)
* */

//内部类
class MyAsyncTask extends AsyncTask<String,Void,Bitmap> {
@Override
protected void onPreExecute() {
super.onPreExecute();
pb.setVisibility(View.VISIBLE);
}

@Override
protected Bitmap doInBackground(String... params) {
//可以写入多个值params[1],params[2].....
String url = params[0];
Bitmap bitmap = null;
URLConnection connection ;
InputStream is ;
try {
connection = new URL(url).openConnection();
is = connection.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bitmap = BitmapFactory.decodeStream(bis);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
is.close();
bis.close();

} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}

@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
pb.setVisibility(View.GONE);
iv.setImageBitmap(bitmap);
}

@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
}


记得在AndroidManifest.xml里面添加访问网络的权限

<uses-permission android:name="android.permission.INTERNET" />


activity_main.xml

<RelativeLayout 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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<Button
android:text="Enter"
android:id="@+id/enter_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<ImageView
android:id="@+id/iv"
android:background="#e6c7c7"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ProgressBar
android:id="@+id/pb"
android:visibility="gone"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>


运行效果



模拟更新进度条

ProgressBarActivity.java

public class ProgressBarActivity extends AppCompatActivity {
private ProgressBar pb;
private MyAsync myAsync;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_progress_bar);

pb = (ProgressBar) findViewById(R.id.pb_simulate);
myAsync = new MyAsync();
myAsync.execute();
}

/**
点击'加载进度条'按钮后程序看起来运行正常.但是,正如上面图示,如果接着点击BACK键,紧接
着再次点击'加载进度条'按钮,会发现进度条的进度一直是零,过了一会才开始更新.这是为什么呢?
根据上述的讲解,我们知道,AsyncTask是基于线程池进行实现的,当一个线程没有结束时,后面的线程是
不能执行的.所以必须等到第一个task的for循环结束后,才能执行第二个task.我们知道,当点击BACK键
时会调用Activity的onPause()方法.为了解决这个问题,我们需要在Activity的onPause()方法中将正在
执行的task标记为cancel状态,在doInBackground方法中进行异步处理时判断是否是cancel状态来决定是
否取消之前的task.
* */

@Override
protected void onPause() {
super.onPause();
if (myAsync != null && myAsync.getStatus() == AsyncTask.Status.RUNNING) {
//cancel方法只是将对应的AsyncTask标记为cancel状态,并不是真正的取消线程的执行.
myAsync.cancel(true);
}
}

class MyAsync extends AsyncTask<Void, Integer, Void> {

//不能在这里更新UI
@Override
protected Void doInBackground(Void... params) {
//模拟进度更新
for (int i = 0; i < 100; i++) {
//如果task是cancel状态,则终止for循环,以进行下个task的执行.
if (isCancelled()){
break;
}
publishProgress(i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

return null;
}

@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if (isCancelled()) {
return;
}

//values的值是publishProgress(i)中i的值,0表示第一个值
pb.setProgress(values[0]);
}
}
}


activity_progress_bar.xml

<LinearLayout 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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="my.com.example.x550v.asynctaskdemo.ProgressBarActivity">
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:id="@+id/pb_simulate"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

</LinearLayout>


运行效果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: