Android异步加载全解析之开篇瞎扯淡

简介: Android异步加载概述 Android异步加载在Android中使用的非常广泛,除了是因为避免在主线程中做网络操作,更是为了避免在显示时由于时间太长而造成ANR,增加显示的流畅性,特别是像ListView、GridView这样的控件,如果getView的时间太长,就会造成非常严重的卡顿,非常影响性能。

Android异步加载

概述

Android异步加载在Android中使用的非常广泛,除了是因为避免在主线程中做网络操作,更是为了避免在显示时由于时间太长而造成ANR,增加显示的流畅性,特别是像ListView、GridView这样的控件,如果getView的时间太长,就会造成非常严重的卡顿,非常影响性能。
本系列将展示在Android中如何进行异步加载操作,并使用ListView来作为演示的对象。

如何下载图像

下载自然是需要使用网络,使用网络就不能在主线程,在主线程就会爆炸。所以我们必须要在非主线程中去下载图像。OK,那么下载使用的方法呢,非常多,这里简单的列举几种

HttpURLConnection

private static Bitmap getBitmapFromUrl(String urlString) {
    Bitmap bitmap;
    InputStream is = null;
    try {
        URL url = new URL(urlString);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        is = new BufferedInputStream(conn.getInputStream());
        bitmap = BitmapFactory.decodeStream(is);
        conn.disconnect();
        return bitmap;
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (is != null)
                is.close();
        } catch (IOException e) {
        }
    }
    return null;
}

非常简单,甚至都没做超时等处理,这里偷个懒。

Drawable

Drawable d = Drawable.createFromStream(is, "url");

也非常简单,只是需要进行下转换。

ListView

这一篇作为开篇,我们还是来扯下淡,这个ListView,大家都用过,最常用的优化也就是使用ViewHolder模式进行复用,避免重复的inflate和findViewById而影响效率,相信大部分的开发者都已经熟知,这里我们还是贴下Adapter的代码:

package com.imooc.listviewacyncloader;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;

import java.util.List;

public class MyAdapterNotUseCaches extends BaseAdapter {

    private LayoutInflater mInflater;
    private List<String> mData;

    public MyAdapterNotUseCaches(Context context, List<String> data) {
        this.mData = data;
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return mData.size();
    }

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        String url = mData.get(position);
        ViewHolder viewHolder = null;
        if (convertView == null) {
            viewHolder = new ViewHolder();
            convertView = mInflater.inflate(R.layout.listview_item, null);
            viewHolder.imageView = (ImageView) convertView.findViewById(R.id.iv_lv_item);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.imageView.setTag(url);
        viewHolder.imageView.setImageResource(R.drawable.ic_launcher);
        return convertView;
    }

    public class ViewHolder{
        public ImageView imageView;
    }
}

确实非常简单哈,最基本的ViewHolder模式使用ListView,不过,这里有点需要注意的:

viewHolder.imageView.setTag(url);

这个其实是非常重要的,为什么重要我们后面会继续说。除了这个地方,其它的部分,如果你能独立写出来,相信你已经击败了10%的开发者了,后面我们再来讲如何击败剩下90%的开发者。

图像

图像我们可以从网络相册里面来获取,这里偶然找到郭神的一篇博客里面的图像地址,就无耻的拿来用了:
public class Images {

    public final static String[] IMAGE_URLS = new String[] {
            "http://img.my.csdn.net/uploads/201407/26/1406383299_1976.jpg",
            "http://img.my.csdn.net/uploads/201407/26/1406383291_6518.jpg",
            "http://img.my.csdn.net/uploads/201407/26/1406383291_8239.jpg",
            "http://img.my.csdn.net/uploads/201407/26/1406383290_9329.jpg",
            "http://img.my.csdn.net/uploads/201407/26/1406383290_1042.jpg",
            "http://img.my.csdn.net/uploads/201407/26/1406383275_3977.jpg",
            "http://img.my.csdn.net/uploads/201407/26/1406383265_8550.jpg",
……

那么我们在MainActivity中就可以导入这些图像了:
package com.imooc.listviewacyncloader;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

import java.util.Arrays;
import java.util.List;


public class MainActivity extends Activity {

    private ListView mListView;
    private List<String> mData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mListView = (ListView) findViewById(R.id.lv);
        mData = Arrays.asList(Images.IMAGE_URLS);
        mListView.setAdapter(……);
    }
}

测试图像搞定~我们后面继续~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


我的Github
我的视频 慕课网






目录
相关文章
|
Android开发 数据格式 XML
Android Loader 异步加载详解二:探寻Loader内部机制
Android Loader 异步加载详解二:探寻Loader内部机制 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/70259914 本文出自【赵彦军的博客】 Android Loader 异步加载详解一:基础概念 Android Loader 异步加载详解二:探寻Loader内部机制 在上一篇文章中,讲解了 Loader 的基本概念。
1201 0
|
Android开发 开发工具 IDE
Android异步加载全解析之IntentService
Android异步加载全解析之IntentService 搞什么IntentService 前面我们说了那么多,异步处理都使用钦定的AsyncTask,再不济也使用的Thread,那么这个IntentService是个什么鬼。
903 0
|
存储 缓存 Java
Android异步加载全解析之引入二级缓存
Android异步加载全解析之引入二级缓存 为啥要二级缓存 前面我们有了一级缓存,为啥还要二级缓存呢?说白了,这就和电脑是一样的,我们电脑有内存和硬盘,内存读取速度快,所以CPU直接读取内存中的数据,但是,内存资源有限,所以我们可以把数据保存到硬盘上,这就是二级缓存,硬盘虽然读取速度慢,但是人家容量大。
593 0
|
缓存 算法 Java
Android异步加载全解析之引入一级缓存
Android异步加载全解析之引入缓存 为啥要缓存 通过对图像的缩放,我们做到了对大图的异步加载优化,但是现在的App不仅是高清大图,更是高清多图,动不动就是图文混排,以图代文,如果这些图片都加载到内存中,必定会OOM。
622 0
|
Java Android开发
Android异步加载全解析之使用AsyncTask
Android异步加载全解析之使用AsyncTask 概述 既然前面提到了多线程,就不得不提到线程池,通过线程池,不仅可以对并发线程进行管理,更可以提高他们执行的效率,优化整个App。当然我们可以自己创建一个线程池,不过这样是很烦的,要创建一个高效的线程池还是挺费事的,不过,Android系统给我吗提供了AsyncTask这样一个类,来帮助我们快速实现多线程开发,它的底层实现,其实就是一个线程池。
1094 0