Android - AsyncTask (SDK 24)

利用AsyncTask给ListView异步加载图片 实现图文混排

#  AsyncTask
 // 无参 无进度显示 有返回值
JSONObjectpublic class NewsTask extends AsyncTask {   
   private Activity activity;  
   private String url;   
   private OnTaskListener listener;   

 //构造方法  将 act 以及 url 传进来  listen实例化    
public NewsTask (Activity activity, String url,OnTaskListener onTaskListener) { 
  this.activity = activity;       
  this.url = url;        
  this.listener = onTaskListener;    
}   

 // 将 url 对应的json数据 转为  JSONObject    
private JSONObject getJsonData(String url){ 
       JSONObject jsonObject = null;        
try { 
   // new URL(url).getConnection.getInputStream 合成           
    String jsonStr = readStream(new URL(url).openStream());          
     jsonObject = new JSONObject(jsonStr);        //json字符串转为 json对象        
} catch (IOException e) {           
 e.printStackTrace();        
}catch (JSONException e) {            
  e.printStackTrace();        
}        return  jsonObject;    
}  
// 转成 json 字符串    
private String readStream (InputStream is){        
  InputStreamReader isr;        
  String result ="";        
try {            
  String line = "";            
  // 通过定义字符集格式 将字节流 转为 字符流
  isr = new InputStreamReader(is,"utf-8");                 
  BufferedReader br = new BufferedReader(isr); // 缓存 策略 Buffer            
  while ((line = br.readLine()) != null){      // 逐行 读 直到为空                
    result += line;            
 }        
} catch (UnsupportedEncodingException e) {            
  e.printStackTrace();        
} catch (IOException e) {            
  e.printStackTrace();        
}        
  return result;    
}    

// 子线程 任务    
@Override
    protected JSONObject doInBackground(Void... params) {       
   return getJsonData(url);    
}    
// execute后  doInBackground前 初始化    
@Override
    protected void onPreExecute() {        
  super.onPreExecute();    
}    
@Override
    protected void onPostExecute(JSONObject jsonObject) {
                      super.onPostExecute(jsonObject);        
  if (jsonObject == null){            
  listener.onFailed("数据为空");        
}else {            
// 成功            
  listener.onSucceed(jsonObject);        
}        
// 注意释放       
   listener = null;        
   activity = null;    
}    
@Override
    protected void onProgressUpdate(Void... values) {
          super.onProgressUpdate(values);
    }
}

# act 
new NewsTask(this, url, new OnTaskListener() {    
@Override    public void onSucceed(JSONObject jsonObject){      
  List beanList = new ArrayList();       
 JSONArray jsonArray = null;      
  //  操作数据      
  try {         
   jsonArray = jsonObject.getJSONArray("data");         
   for (int i=0;i beanList;
    private LayoutInflater inflater;
    private Context context;
    private ImageThreadLoader imgLoader;
    private int startIdx, endIdx;
    public static String[] imgUrls;  //创建静态数组
    private boolean firstFlag;

    public NewsAdapter(List beanList, Context context) {
        this.beanList = beanList;
        this.context = context;
        inflater = LayoutInflater.from(context);
        imgLoader = new ImageThreadLoader();

        // 将所有 newsImgUrl 单独出来成为一个静态数组
      imgUrls = new String[beanList.size()];
      for (int i=0;i 0){
        // 第一次 第一屏 加载 (此时 未主动滑动 且 totalItemCount不为0而且已经计算出来)
        imgLoader.loadImages(startIdx,endIdx);
        firstFlag = false;
    }
}
    // ViewHolder 内部类
    private class HolderView{
        private ImageView mImgView;
        private TextView mTitle,mContent;
    }

# Thread

public class ImageThreadLoader { 
   private ImageView mImageView; 
   private String mUrl;
   // Lru(least recently used近期最少使用 算法)  LruCache是Android基于LRU封装的缓存 (类型类似于map)
private LruCache mCache;
private ListView mListView;
private Set mVisiableTasks;

    //  匿名Handler  处理子线程和主线程的消息传递 更新UI
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            // url 一一对应ImgView  避免 多次赋值 以及 赋值混乱
            if (mImageView.getTag() == mUrl){
                mImageView.setImageBitmap((Bitmap) msg.obj);
            }
        }
    };
    public void getImageByThrea(ImageView imgView, final String imgUrl){
        // 存储 imgView 和 url
        mImageView = imgView;
        mUrl = imgUrl;
        //
        new Thread(){
            @Override
            public void run() {
                super.run();
                Bitmap bitmap = getBitmapBy(imgUrl);
                Message msg = new Message();
                msg.obj = bitmap;
                mHandler.sendMessage(msg);   //发送消息
            }
        }.start();
    }
    private Bitmap getBitmapBy(String imgUrl)  {
        Bitmap bitmap = null;
        InputStream is = null;
        URL url = null;
        try {
            url = new URL(imgUrl);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        HttpURLConnection connection = null;
        try {
            connection = (HttpURLConnection) url.openConnection();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            is = connection.getInputStream();
        } catch (IOException e) {            e.printStackTrace();        }
        BufferedInputStream bis = new BufferedInputStream(is);
        bitmap = BitmapFactory.decodeStream(bis);
        return bitmap;
    }

// 构造方法  外界 实例化ImageThreadLoader的成员变量 保证只有一个 LruCache对象
public ImageThreadLoader() {
mListView = listView;
// 初始化 集合
mVisiableTasks = new HashSet<>();
    // 获得当前 最大可以内存
    int maxSize = (int) Runtime.getRuntime().maxMemory();
    //  分多少内存给缓存
    int cacheSize = maxSize / 4;
    // 实例化
    mCache = new LruCache(cacheSize){
        // 必须实现的方法 返回每次存入时 key 对应的value的大小
        @Override
        protected int sizeOf(String key, Bitmap value) {
            return value.getByteCount();
        }
    };
}
private void addToCache(String key,Bitmap value){
    if (getFromCache(key) == null){
  // 内存中不存在
        mCache.put(key,value);
    }
}
private Bitmap getFromCache(String key){
    return mCache.get(key);
}
//  AsyncTask方式
public void setImageByAsyncTask(ImageView imgView,String url){
    mImageView = imgView;
    mUrl = url;
    // 先从缓存中取数据
    Bitmap bitmap = getFromCache(url);
    if (bitmap == null){
        // 没有缓存 下载
        new ImageAsycTask().execute(url);
    }else {
        imgView.setImageBitmap(bitmap);
    }
}

// 加载序列中 指定的所有图片
public void loadImages(int startIdx,int endIdx){
    for (int i=startIdx;i{
private String taskImgUrl;
public ImageAsycTask(String taskImgUrl) {
    this.taskImgUrl = taskImgUrl;
}
    @Override
    protected Bitmap doInBackground(String... params) {
        String url = params[0];
        Bitmap bitmap = getBitmapBy(url);
        if (bitmap != null){
            // 加入到缓存
            addToCache(url,bitmap);
        }
        return bitmap;
    }
    @Override
    protected void onPostExecute(Bitmap bitmap) {
        super.onPostExecute(bitmap);
       ImageView imgView = (ImageView) mListView.findViewWithTag(taskImgUrl);
if (imgView != null && bitmap != null){
    imgView.setImageBitmap(bitmap);
}
mVisiableTasks.remove(this);
    }
}
}

#  接口
public interface OnTaskListener  {
    // 将Task独立出来以及 定义接口和将返回值 定义成 JSONObject  都是为了封装
    public void onSucceed(JSONObject jsonObject);
    public void onFailed(String msg);
}

链接

AsyncTask源码分析

知乎

你可能感兴趣的:(Android - AsyncTask (SDK 24))