Android基础之AsyncTask详解,巨细哟
2016-05-27 17:11
423 查看
构建AsyncTask子类参数
因为他是一个抽象类所有继承他之后需要重写下面三个泛型参数
Params:启动任务时,输入参数的类型。
Progress:后台任务执行中返回进度值的类型
Result:后台执行任务完成后返回结果的类型
构建AsyncTask子类的回调方法
dolnBackground:必须重写,异步执行后台程序将要完成的任务。
onPreExecute:执行后台耗时操作前被调用,用户通常会做一些准备工作,如一些初始化的操作。
onPostExecute():当dolnBackground()完成后,系统会自动调用该方法,并将dolnBackground()方法的返回值传给该方法。顾名思义就是展示我们所处理完的一个结果。
onProgressUpdate():在dolnBackground()方法中调用publishProgress()方法更新任务就会触发该方法。
程序的调动顺序是:
onPreExecute——>dolnBackground——>onPostExecute(没有调用publishProgress ())
传递进度:在dolnBackground()中调用publishProgress()方法的时候,就可以将一个进度值作为一参数传给onProgressUpdate(),我们就可以在onProgressUpdate()中得到这个参数,从而应用于更新一个异步进程的完成进度。
实例:
下载图片,并且显示(只是下载到缓存中。程序kill后需要再次下载)
package com.example.administrator.android_asynctask;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URL;
import java.net.URLConnection;
/**
* Created by Administrator on 2016/5/26.
*/
public class ImageTestextends Activity {
private ImageView
imageView;
private ProgressBar
progressBar;
private static String
URL = "http://img4.duitang.com/uploads/item/201308/10/20130810135200_tyE55.jpeg";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.image);
imageView = (ImageView) findViewById(R.id.imageView1);
progressBar = (ProgressBar) findViewById(R.id.pb);
new MyAsyncTask_1().execute(URL);
}
class MyAsyncTask_1
extends AsyncTask<String, Void, Bitmap> {
@Override
//在doInBackground启动前 ,显示progressBar
protected void onPreExecute() {
super.onPreExecute();
progressBar.setVisibility(View.VISIBLE);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
//隐藏progressBar
progressBar.setVisibility(View.GONE);
//传递bimap
imageView.setImageBitmap(bitmap);
Log.d("xyx","onPostExecute_bitmap=" + bitmap);
}
@Override
//参数是可变长数组
//<URL类型,进度值类型,返回值类型>
//doInBackground方法是开启一个异步线程做耗时操作的
protected Bitmap doInBackground(String... params) {
//取出对应的URL
String url = params[0];
Bitmap bitmap = null;
Log.d("xyx","url=" + url);
//定义网络链接对象
//以前的
// URLConnection connection;
HttpURLConnection connection;
//用于获取的数据的输入流
InputStream inputStream = null;
try {
//通过openConnection方法获取connection对象,获取网络连接对象
Thread.sleep(3000);
//原来方法
// connection = new URL(url).openConnection();
connection = (HttpURLConnection) new URL(url).openConnection();
connection.setDoInput(true);
connection.setRequestMethod("GET");
connection.connect();
//获取一个输入流
inputStream = connection.getInputStream();
BufferedInputStream bis = new BufferedInputStream(inputStream);
//通过,decodeStream解析输入流流
bitmap = BitmapFactory.decodeStream(bis);
inputStream.close();
bis.close();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return bitmap;
}
}
}
模拟进度条
package com.example.administrator.android_asynctask;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.util.List;
/**
* Created by Administrator on 2016/5/27.
*/
public class progressBarTest extends Activity {
private ProgressBar pb;
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progress);
pb= (ProgressBar) findViewById(R.id.pb2);
new MyAsyncTask_ProgressBar().execute();
}
class MyAsyncTask_ProgressBar extends AsyncTask<Void, Integer, Void> {
@Override
protected Void doInBackground(Void... params) {
for (int i = 0; i <=100; i++) {
try {
Thread.sleep(300);
publishProgress(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
pb.setProgress(values[0]);
}
}
}
取消AsyncTask
AsyncTask机制:因为他的底层是线程池 ,所有多次开始——返回后,他会卡住只有等之前的Task全部完成后,才会开始新的Task,而且,我们doInBackground中用的是for循环,所以只有等for循环结束,才会去执行下一个Task;所以会造成,多次进入后,进度条就会卡住的BUG,如何解决呢?
方案:
AsyncTask和Activaty的生命周期保持一致,也就是Activity生命周期走到onPause的时候,把AsyncTask干掉就好了。
失败原因:
下载部分:
内部类是要放在外部类里面的
图片无法显示的原因:bitmap通过bitmap = BitmapFactory.decodeStream(bis);这方法无法获得bitmap值;
解决办法,网址有问题,不是图片网址
附带博客一个,解决其他问题:http://blog.csdn.net/andypan1314/article/details/6670320
总结:
必须在UI线程中创建AsyncTask的实例
必须在UI线程中调用AsyncTask的execute()方法
重写的四个方法是系统自动调用的,不应手动调用
每个AsyncTask只能被执行一次,多次调用将会引发异常
dolnBackground只有这方法是在其他线程的,其他方法都是在UI线程。
因为他是一个抽象类所有继承他之后需要重写下面三个泛型参数
Params:启动任务时,输入参数的类型。
Progress:后台任务执行中返回进度值的类型
Result:后台执行任务完成后返回结果的类型
构建AsyncTask子类的回调方法
dolnBackground:必须重写,异步执行后台程序将要完成的任务。
onPreExecute:执行后台耗时操作前被调用,用户通常会做一些准备工作,如一些初始化的操作。
onPostExecute():当dolnBackground()完成后,系统会自动调用该方法,并将dolnBackground()方法的返回值传给该方法。顾名思义就是展示我们所处理完的一个结果。
onProgressUpdate():在dolnBackground()方法中调用publishProgress()方法更新任务就会触发该方法。
程序的调动顺序是:
onPreExecute——>dolnBackground——>onPostExecute(没有调用publishProgress ())
传递进度:在dolnBackground()中调用publishProgress()方法的时候,就可以将一个进度值作为一参数传给onProgressUpdate(),我们就可以在onProgressUpdate()中得到这个参数,从而应用于更新一个异步进程的完成进度。
实例:
下载图片,并且显示(只是下载到缓存中。程序kill后需要再次下载)
package com.example.administrator.android_asynctask;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URL;
import java.net.URLConnection;
/**
* Created by Administrator on 2016/5/26.
*/
public class ImageTestextends Activity {
private ImageView
imageView;
private ProgressBar
progressBar;
private static String
URL = "http://img4.duitang.com/uploads/item/201308/10/20130810135200_tyE55.jpeg";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.image);
imageView = (ImageView) findViewById(R.id.imageView1);
progressBar = (ProgressBar) findViewById(R.id.pb);
new MyAsyncTask_1().execute(URL);
}
class MyAsyncTask_1
extends AsyncTask<String, Void, Bitmap> {
@Override
//在doInBackground启动前 ,显示progressBar
protected void onPreExecute() {
super.onPreExecute();
progressBar.setVisibility(View.VISIBLE);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
//隐藏progressBar
progressBar.setVisibility(View.GONE);
//传递bimap
imageView.setImageBitmap(bitmap);
Log.d("xyx","onPostExecute_bitmap=" + bitmap);
}
@Override
//参数是可变长数组
//<URL类型,进度值类型,返回值类型>
//doInBackground方法是开启一个异步线程做耗时操作的
protected Bitmap doInBackground(String... params) {
//取出对应的URL
String url = params[0];
Bitmap bitmap = null;
Log.d("xyx","url=" + url);
//定义网络链接对象
//以前的
// URLConnection connection;
HttpURLConnection connection;
//用于获取的数据的输入流
InputStream inputStream = null;
try {
//通过openConnection方法获取connection对象,获取网络连接对象
Thread.sleep(3000);
//原来方法
// connection = new URL(url).openConnection();
connection = (HttpURLConnection) new URL(url).openConnection();
connection.setDoInput(true);
connection.setRequestMethod("GET");
connection.connect();
//获取一个输入流
inputStream = connection.getInputStream();
BufferedInputStream bis = new BufferedInputStream(inputStream);
//通过,decodeStream解析输入流流
bitmap = BitmapFactory.decodeStream(bis);
inputStream.close();
bis.close();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return bitmap;
}
}
}
模拟进度条
package com.example.administrator.android_asynctask;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.util.List;
/**
* Created by Administrator on 2016/5/27.
*/
public class progressBarTest extends Activity {
private ProgressBar pb;
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progress);
pb= (ProgressBar) findViewById(R.id.pb2);
new MyAsyncTask_ProgressBar().execute();
}
class MyAsyncTask_ProgressBar extends AsyncTask<Void, Integer, Void> {
@Override
protected Void doInBackground(Void... params) {
for (int i = 0; i <=100; i++) {
try {
Thread.sleep(300);
publishProgress(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
pb.setProgress(values[0]);
}
}
}
取消AsyncTask
AsyncTask机制:因为他的底层是线程池 ,所有多次开始——返回后,他会卡住只有等之前的Task全部完成后,才会开始新的Task,而且,我们doInBackground中用的是for循环,所以只有等for循环结束,才会去执行下一个Task;所以会造成,多次进入后,进度条就会卡住的BUG,如何解决呢?
方案:
AsyncTask和Activaty的生命周期保持一致,也就是Activity生命周期走到onPause的时候,把AsyncTask干掉就好了。
package com.example.administrator.android_asynctask; import android.app.Activity; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.widget.ProgressBar; import android.widget.TextView; import java.util.List; /** * Created by Administrator on 2016/5/27. */ public class progressBarTest extends Activity { private ProgressBar pb; private TextView tv; private MyAsyncTask MTP; MyAsyncTask_ProgressBar mb = new MyAsyncTask_ProgressBar(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.progress); pb = (ProgressBar) findViewById(R.id.pb2); mb.execute(); } protected void onPause() { super.onPause(); if ((mb != null) && (mb.getStatus() == AsyncTask.Status.RUNNING)) { //这只是把MTP标记为cancel状态,不是真正的取消了线程,那我就需要, // 给doInBackground中的for循环设定判断条件, // 并且给onProgressUpdate进行判断是否要更新 mb.cancel(true); } } class MyAsyncTask_ProgressBar extends AsyncTask<Void, Integer, Void> { @Override protected Void doInBackground(Void... params) { for (int i = 0; i <= 100; i++) { //是否有cancel状态 if (isCancelled()) { break; } try { Thread.sleep(300); publishProgress(i); } catch (InterruptedException e) { e.printStackTrace(); } } return null; } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); if (isCancelled()) { return; } pb.setProgress(values[0]); } } }
失败原因:
下载部分:
内部类是要放在外部类里面的
图片无法显示的原因:bitmap通过bitmap = BitmapFactory.decodeStream(bis);这方法无法获得bitmap值;
解决办法,网址有问题,不是图片网址
附带博客一个,解决其他问题:http://blog.csdn.net/andypan1314/article/details/6670320
总结:
必须在UI线程中创建AsyncTask的实例
必须在UI线程中调用AsyncTask的execute()方法
重写的四个方法是系统自动调用的,不应手动调用
每个AsyncTask只能被执行一次,多次调用将会引发异常
dolnBackground只有这方法是在其他线程的,其他方法都是在UI线程。
相关文章推荐
- Android适配参考
- Android使用WindowManager构造悬浮view
- Androin学习笔记五十八:android触控,先了解MotionEvent
- Android几个bitmap相关的方法
- Android设计模式--适配器模式--Adapter入门
- android studio 真机运行的时候gradle 报错 AGPBI: {"kind":"SIMPLE","text":"Error: C
- Android中糟糕的AsyncTask
- Android studio 下JNI编程实例并生成so库
- Android上的MVP模式
- Android开发设计模式之——单例模式
- 1、读取Android工程下的配置文件
- Android实现应用下载并自动安装apk包
- Android Studio之常用设置
- Android中如何通过程序打开或关闭GPS
- Android 自定义View属性相关细节
- Android CardView 的使用
- Android Studio 项目导入
- android 基础 加密 简易加密BASE64Decoder
- Android Studio 安装完成,启动时一直download Components解决办法
- 自定义view实现涂鸦(画板)功能