使用 AsyncTask 进行异步加载 ListView 图文并排

##一些 AsyncTask 的知识

  • AsyncTask<Params,Progress,Results>是一个抽象类,通常用于被继承需要指定三个参数

    1
    2
    3
    Params: 启动任务时输入参数的类型
    Progress: 后台任务进行中返回进度值的类型
    Results: 后台任务执行完毕后返回结果的类型
  • 必须重写 doInBackground() 方法 这是异步执行后台线程任务将要完成的任务 在这里操作耗时操作

  • onPreExecute() 执行后台耗时操作前被调用,用来进行初始化操作

  • onPostExecute() 当doInBackground() 方法完成后会自动调用这个方法,并将 doInBackground() 方法中返回的值传递给该方法

  • onProgressUpdate() 在doInBackground() 方法中调用publishProgress() 方法更新任务的执行进度后就会调用该方法

##一些 Tips

  • 在 Android Studio 中 Command + N 后点击 Override Methods 可以选择重载函数

##代码分析

  • 使用 Gson 解析服务器返回的 Json 数据(具体使用详见-> 解析 Json 数据

在这个 Demo 中我需要解析一个 当天天气的温度和当天天气的图片的URL 出来,并解析为 List ,传递给 ListView 的 Adapter

  • 新建一个类 WeatherBean
1
2
3
4
5
public class WeatherBean
{
public String weatherUrl;
public String weatherTem;
}
  • 写一个方法用于解析 Json 数据中返回的 当天天气的温度和当天天气的图片的URL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public List<WeatherBean> parseJsonWithGsonTest(String jsonData)
{
List<WeatherBean> weatherBeanList = new ArrayList<>();
Gson gson = new Gson();
WeatherInfo weatherInfo = gson.fromJson(jsonData, WeatherInfo.class);
try {
for (int i = 0;i<3;i++)
{
WeatherBean weatherBean = new WeatherBean();
weatherBean.weatherUrl = weatherInfo.getResults().get(0).getWeather_data().get(i+1).getDayPictureUrl();
weatherBean.weatherTem = weatherInfo.getResults().get(0).getWeather_data().get(i+1).getTemperature();
weatherBeanList.add(weatherBean);
}
}catch (Exception e)
{e.printStackTrace();}

return weatherBeanList;
}
  • 在 MainActivity 中建立一个类,并 new 一个对象调用 MyAsyncTask 进行异步加载

new MyAsyncTask().execute(response);//response 是通过访问服务器返回的json数据
传入服务器返回的json数据,接着用parseJsonWithGsonTest 方法去解析得到天气图的url和tem,返回url和tem到onPostExecute中设置给 ListView 的 adapter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class MyAsyncTask extends AsyncTask<String,Void,List<WeatherBean>>
{
@Override
protected List<WeatherBean> doInBackground(String... params)
{
Log.d(TAG,"传入的url是 "+params[0]);
//传入的是服务器返回的json数据,接着用parseJsonWithGsonTest 方法去解析得到天气图的url和tem,返回 url和tem到onPostExecute中
return new ParseJson().parseJsonWithGsonTest(params[0]);
}
@Override
protected void onPostExecute(List<WeatherBean> weatherBeans)
{
super.onPostExecute(weatherBeans);
WeatherListAdapter adapter = new WeatherListAdapter(MainActivity.this,weatherBeans);
weatherInfoListView.setAdapter(adapter);
}
}
  • 写 ListView 的 Adapter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public class WeatherListAdapter extends BaseAdapter {
private List<WeatherBean> weatherBeanList;
private LayoutInflater layoutInflater;

public WeatherListAdapter (Context context,List<WeatherBean> data)
{
weatherBeanList = data;
layoutInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return weatherBeanList.size();
}

@Override
public Object getItem(int position) {
return weatherBeanList.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView==null)
{
viewHolder = new ViewHolder();
convertView = layoutInflater.inflate(R.layout.weatherinfo,null);
viewHolder.imageView = (ImageView)convertView.findViewById(R.id.weatherIamge);
viewHolder.textView = (TextView) convertView.findViewById(R.id.weatherInfo);
convertView.setTag(viewHolder);
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.imageView.setImageResource(R.mipmap.ic_launcher);
String url = weatherBeanList.get(position).weatherUrl;
Log.d("WeatherListAdapter","weatherUrl is "+url);
viewHolder.imageView.setTag(url);
new PictureLoader().showImageByAsyncTask(viewHolder.imageView,url);//调用异步加载图片
viewHolder.textView.setText(weatherBeanList.get(position).weatherTem);
return convertView;
}
class ViewHolder
{
public ImageView imageView;
public TextView textView;
}
}

  • 通过 AsyncTask 异步加载图片,通过传入的 url 获取 bitmap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public class PictureLoader
{
public void showImageByAsyncTask(ImageView imageView,String url)
{
//MyAsyncTask myAsyncTask = new MyAsyncTask(imageView,url);
//myAsyncTask.execute(url);
new ShowPicAsyncTask(imageView, url).execute(url);

}
public Bitmap getBitmapFromUrl(String stringUrl)
{
Bitmap bitmap = null;
InputStream inputStream = null;
try {
URL url = new URL(stringUrl);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
inputStream = new BufferedInputStream(httpURLConnection.getInputStream());
bitmap = BitmapFactory.decodeStream(inputStream);
httpURLConnection.disconnect();
return bitmap;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
//异步加载天气列表里的天气图
private class ShowPicAsyncTask extends AsyncTask<String,Void,Bitmap>
{
private ImageView mImageView;
private String mUrl;
public ShowPicAsyncTask(ImageView imageView,String url)
{
mImageView = imageView;
mUrl = url;
}
@Override
protected Bitmap doInBackground(String... params) {
getBitmapFromUrl(params[0]);
return getBitmapFromUrl(params[0]);
}

@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if (mImageView.getTag().equals(mUrl)) {
mImageView.setImageBitmap(bitmap);
}
}
}
}

源码在 Github 上 因为是从我写的一个重构过的天气 Demo 中摘出来的,写得比较乱

使用 AsyncTask 进行异步加载 ListView 图文并排

https://ppting.me/2015/10/09/2015_10_09_asyncTask/

作者

PPTing

发布于

2015-10-09

更新于

2022-02-12

许可协议

评论