#Android异步加载图片
来源:互联网 发布:科勒淘宝商城旗舰店 编辑:程序博客网 时间:2024/06/05 00:12
一、概述
Android中异步加载图片的方式有俩种,此文通过从服务器取出的Json数据后,通过这俩种方式去加载服务器的图片数据。
二、案例描述:
三、实现编码思路
1、写布局2、取到服务器的Json转成JavaBean保存在List中当数据源3、在适配器中把数据源对应显示在ListView4、在适配器显示图片时开启异步线程去服务器读取照片5、图片缓存优化下
1、布局xml文件代码
就一个简单的ListView + 每一个Item的布局
ListView在主布局<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="com.kuxiao.tran.studyActivity.MainActivity"> <ListView android:id="@+id/id_lv_news" android:layout_width="match_parent" android:layout_height="match_parent" /></RelativeLayout>
每一个Item的布局<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:orientation="horizontal" android:padding="4dp" android:layout_height="wrap_content"> <ImageView android:layout_marginLeft="5dp" android:layout_width="64dp" android:layout_height="64dp" android:id="@+id/id_iv_icon" android:src="@mipmap/ic_launcher"/> <LinearLayout android:layout_marginLeft="3dp" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_marginTop="5dp" android:id="@+id/id_tv_title" android:textSize="18dp" android:text="标题" android:paddingLeft="3dp" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:layout_marginTop="3dp" android:id="@+id/id_tv_context" android:textSize="15dp" android:paddingLeft="4dp" android:text="内容" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout></LinearLayout>
2、取到服务器的Json转成JavaBean保存在List中当数据源
package com.kuxiao.tran.studyActivity;import android.os.AsyncTask;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.widget.ListView;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.lang.String;import java.net.MalformedURLException;import java.net.URL;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity { private ListView mListView; //访问服务器url private static final String url_news = "http://172.46.159.87:8080/News/NewsAction"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mListView = (ListView) findViewById(R.id.id_lv_news); new MyAsynctask().execute(url_news); } //利用异步线程访问服务取到数据源 class MyAsynctask extends AsyncTask<String, Void, List<NewsBean>> { @Override protected List<NewsBean> doInBackground(String... params) { String url = params[0]; return getNewsBean(url); } @Override protected void onPostExecute(List<NewsBean> newsBeans) { MyAdapter myAdapter = new MyAdapter(MainActivity.this,newsBeans); mListView.setAdapter(myAdapter); } } //解析Json数据成NewsBean private List<NewsBean> getNewsBean(String url) { List<NewsBean> mList = new ArrayList<>(); InputStream mIs = null; try { URL mUrl = new URL(url); mIs = mUrl.openStream(); String json = getJsonFromInputStream(mIs); Log.i("text",json); JSONObject jsonObject = new JSONObject(json); JSONArray jsonArray = jsonObject.getJSONArray("data"); for (int i = 0; i <jsonArray.length();i++) { jsonObject = (JSONObject) jsonArray.get(i); NewsBean newsBean = new NewsBean(); newsBean.setStr_context(jsonObject.getString("context")); newsBean.setStr_icon(jsonObject.getString("Str_icon")); newsBean.setStr_title(jsonObject.getString("title")); mList.add(newsBean); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { } catch (JSONException e) { e.printStackTrace(); } return mList; } //将流读取成Json字符串 private String getJsonFromInputStream(InputStream inputStream) { String json = ""; String str; InputStreamReader mIsr = new InputStreamReader(inputStream); BufferedReader mBfr = new BufferedReader(mIsr); try { while (null != (str = mBfr.readLine())) { json += str; } } catch (IOException e) { e.printStackTrace(); } finally { try { mBfr.close(); } catch (IOException e) { e.printStackTrace(); } } return json; }}
JavaBean代码
package com.kuxiao.tran.studyActivity;public class NewsBean { private String Str_title; private String str_context; private String str_icon; public String getStr_title() { return Str_title; } public void setStr_title(String str_title) { Str_title = str_title; } public String getStr_icon() { return str_icon; } public void setStr_icon(String str_icon) { this.str_icon = str_icon; } public String getStr_context() { return str_context; } public void setStr_context(String str_context) { this.str_context = str_context; }}3、在适配器中把数据源对应显示在ListView上package com.kuxiao.tran.studyActivity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.AsyncTask;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;import java.io.IOException;import java.io.InputStream;import java.net.MalformedURLException;import java.net.URL;import java.util.List;public class MyAdapter extends BaseAdapter { private List<NewsBean> mList;//数据源 private LayoutInflater mInflater;//每一个item布局的转化 private BitmapCache mBitmapCache = null;//缓存 public MyAdapter(Context context, List<NewsBean> params) { mInflater = LayoutInflater.from(context); this.mList = params; mBitmapCache = new BitmapCache(); } @Override public int getCount() { return mList.size(); } @Override public Object getItem(int position) { return mList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder mViewHolder; //ListView的缓存机制中判断convertView是否存在 if (convertView == null) { mViewHolder = new ViewHolder(); convertView = mInflater.inflate(R.layout.item, null); mViewHolder.iv_icon = (ImageView) convertView.findViewById(R.id.id_iv_icon); mViewHolder.tv_title = (TextView) convertView.findViewById(R.id.id_tv_title); mViewHolder.tv_context = (TextView) convertView.findViewById(R.id.id_tv_context); convertView.setTag(mViewHolder); } else { mViewHolder = (ViewHolder) convertView.getTag(); } //给对应的viewHolder对象保存的控件赋值 mViewHolder.tv_context.setText(mList.get(position).getStr_context()); mViewHolder.tv_title.setText(mList.get(position).getStr_title()); new MyAsnyctask(mViewHolder.iv_icon, position,mBitmapCache).execute(mList.get(position).getStr_icon()); return convertView; } //利用ViewHolder对象避免重复的findViewById寻找控件的操作 class ViewHolder { ImageView iv_icon; TextView tv_context; TextView tv_title; }}
4、在适配器显示图片时开启异步线程去服务器读取照片(第一种方式,利用Asynctask类)
在MyAdapter类中写一个内部类,代码如下
class MyAsnyctask extends AsyncTask<String, Void, Bitmap> { private ImageView imageView; private int position; private static final String url = "http://172.46.159.87:8080/News/NewsImage/"; private BitmapCache mBitmapCache = null; public MyAsnyctask(ImageView imageView, int position,BitmapCache mBitmapCache) { this.imageView = imageView; this.position = position; imageView.setTag(this.position); this.mBitmapCache = mBitmapCache; } @Override protected Bitmap doInBackground(String... params) { Bitmap bitmap; if (mBitmapCache.getBitmap(this.position + "") == null) { String imageName = params[0]; bitmap = getBitmap(imageName); } else { bitmap = mBitmapCache.getBitmap(position + ""); } return bitmap; } //通过Url向服务器取图片 private Bitmap getBitmap(String imageName) { Bitmap bitmap = null; InputStream mIs = null; try { URL url = new URL(MyAsnyctask.url + imageName); mIs = url.openStream(); bitmap = BitmapFactory.decodeStream(mIs); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { mIs.close(); } catch (IOException e) { e.printStackTrace(); } } return bitmap; } @Override protected void onPostExecute(Bitmap bitmap) { if (null != imageView && null != bitmap) { if (imageView.getTag() == position) { imageView.setImageBitmap(bitmap); } } } }
5、另一种方式使用Handller+子线线程的方式实现异步加载,代码如下
package com.kuxiao.tran.studyActivity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Handler;import android.os.Message;import android.widget.ImageView;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;public class ImageLoader extends Thread { private ImageView mImageView; private String mImageName; private int position; private static final String url = "http://172.46.130.144:8080/News/NewsImage/"; public ImageLoader(ImageView mImageView, String imageName, int position) { this.mImageName = imageName; this.mImageView = mImageView; this.position = position; } Handler handler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 0) { if (mImageView.getTag() == ImageLoader.this.position) { Bitmap bitmap = (Bitmap) msg.obj; mImageView.setImageBitmap(bitmap); } } } }; @Override public void run() { try { URL url1 = new URL(url + mImageName); HttpURLConnection urlConnection = (HttpURLConnection) url1.openConnection(); if (urlConnection.getResponseCode() == 200) { InputStream mIs = url1.openStream(); Bitmap bitmap = BitmapFactory.decodeStream(mIs); this.mImageView.setTag(this.position); handler.obtainMessage(0, bitmap).sendToTarget(); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }}
6、利用BitmapCache类进行下缓存优化,代码如下
package com.kuxiao.tran.studyActivity;import android.graphics.Bitmap;import android.util.Log;import android.util.LruCache;public class BitmapCache { private LruCache<String, Bitmap> mLruCache; public BitmapCache() { //获取最大运行时的最大内存 int max = (int) (Runtime.getRuntime().maxMemory() / 8); mLruCache = new LruCache<String, Bitmap>(max) { @Override protected int sizeOf(String key, Bitmap value) { //设置每一次缓存的大小 return value.getByteCount(); } }; } //缓存一个Bitmap对象 public void saveBitmap(String key, Bitmap value) { mLruCache.put(key, value); } //取出一个Bitmap对象 public Bitmap getBitmap(String key) { return mLruCache.get(key); }}
四、特别说明:本人大四的小白,自学的android编程,如有不妥之处,多谢指出,服务器端的代码我就不贴出来了,有需要的朋友可以联系我QQ:953751759,Json数据生成不懂的,可以看我博客中的Json数据生成。
上述中在给ImageView设置Tag的是用的ListView中的位置,并没有用照片的URL,是因为本人服务器生成的Json数据的照片的名字相同,图片只有一张,所以Url不适合设置成Tag,大家在练习的时候注意下。
0 0
- android异步加载图片
- android 异步加载图片
- android异步加载图片
- android异步加载图片
- Android 异步加载图片
- Android 异步加载图片
- Android图片异步加载
- Android图片异步加载
- Android图片异步加载
- Android异步加载图片
- android异步加载图片
- Android图片异步加载
- Android 图片异步加载
- android异步加载图片
- 异步图片加载 Android
- Android 图片异步加载
- Android 图片异步加载
- Android 异步加载图片
- Becoming an Xperf Xpert Part 7: Slow Profile Load and Our Very First Stack WalkHi my name is Randolp
- 项目管理中的需求变更分析和解决之道
- Java for循环实例,嵌套循环
- MYSQL 双机数据同步备份(主从、双Master)
- NoSuchBeanDefinitionException: No qualifying bean of type
- #Android异步加载图片
- RxJava操作符总结
- Zigbee编程软件 IAR ew8051
- script基本包装类型
- 对各种引用的简单了解
- Shiro大神链接
- MFC中ANSI与Unicode字符转换最简单方法
- ORA-12154: TNS: 无法解析指定的连接标识符
- MVVM Light Toolkit使用指南