Android实现异步加载

效果图

代码

public class ImageLoader {

    private InputStream inputStream;
    private HttpURLConnection conn;
    private ImageView mImageview;
    private LruCache mLrucache;
    private ListView mlistview;
    private String threadUrl;
    private Set tasks;
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if(mImageview.getTag().equals(threadUrl)){
                    mImageview.setImageBitmap((Bitmap) msg.obj);
            }
        }
    };

    public ImageLoader(ListView listView){
        mlistview = listView;
        tasks = new HashSet<>();
        int maxMemory = (int) Runtime.getRuntime().maxMemory();
        int cacheSize = maxMemory/8;
        mLrucache = new LruCache(cacheSize){
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                return bitmap.getByteCount();
            }
        };
    }

    public void addBitmapToCache(String url,Bitmap bitmap){
        if(getBitmapFromCache(url)==null){
            mLrucache.put(url,bitmap);
        }
    }

    public Bitmap getBitmapFromCache(String mUrl){
        return mLrucache.get(mUrl);
    }

    public void showImageByThread(ImageView imageView, final String url){
        mImageview = imageView;
        threadUrl = url;
        new Thread(){
            @Override
            public void run() {
                super.run();
                Bitmap bitmap = getBitmapFromUrl(url);
                Message message = Message.obtain();
                message.obj = bitmap;
                mHandler.sendMessage(message);
            }
        }.start();
    }
    public Bitmap getBitmapFromUrl(String urlString){
        Bitmap bitmap = null;
        try {
            URL url = new URL(urlString);
            conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(2000);
            conn.setReadTimeout(2000);
            if(conn.getResponseCode()==200){
                inputStream = new BufferedInputStream(conn.getInputStream());
                 bitmap = BitmapFactory.decodeStream(inputStream);
                return bitmap;
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            conn.disconnect();
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    public void showImageByAsyncTask(ImageView imageView,String url){
        Bitmap bitmap = getBitmapFromCache(url);
        if(bitmap != null){
            imageView.setImageBitmap(bitmap);
        }else{
            //getView的时候不去下载
//            new NewsTask(url).execute(url);
            imageView.setImageResource(R.mipmap.ic_launcher);
        }
    }
    private class NewsTask extends AsyncTask{
        private String mUrl;
        public NewsTask(String url){
            mUrl = url;
        }
        @Override
        protected Bitmap doInBackground(String... params) {
            String url = params[0];
            Bitmap bitmap = getBitmapFromUrl(url);
            if(bitmap!=null){
                addBitmapToCache(url,bitmap);
            }
            return bitmap;
        }
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
//            if(mImageview.getTag().equals(mUrl)){
//                mImageview.setImageBitmap(bitmap);
//            }
            ImageView imageView = (ImageView) mlistview.findViewWithTag(mUrl);
            if(imageView!=null&&bitmap!=null){
                imageView.setImageBitmap(bitmap);
            }
            tasks.remove(this);
        }
    }

    public void loadImages(int start,int end){
        for (int i = start; i < end; i++) {
            String url = NewsAdapter.URLS[i];
            Bitmap bitmap = getBitmapFromCache(url);
            if(bitmap != null){
                ImageView imageView = (ImageView) mlistview.findViewWithTag(url);
                imageView.setImageBitmap(bitmap);
            }else{
                NewsTask task = new NewsTask(url);
                task.execute(url);
                tasks.add(task);
            }
        }
    }
    public void canCellAllTask(){
        for (NewsTask task:tasks) {
            task.cancel(false);
        }
    }
}
public class NewsAdapter extends BaseAdapter implements AbsListView.OnScrollListener{
    private Context context;
    private List listDataBeen;
    private LayoutInflater mInflate;
    private String url;
    private ImageLoader mImageLoader;
    private int mStart;
    private int mEnd;
    public static String[] URLS;
    private ListView mListview;
    private boolean isFirstShow = true;
    public NewsAdapter(Context context, List dataBeen,ListView listView){
        this.context = context;
        this.listDataBeen = dataBeen;
        mInflate = LayoutInflater.from(context);
        mListview = listView;
        mImageLoader = new ImageLoader(mListview);
        URLS = new String[dataBeen.size()];
        for(int i = 0;i< dataBeen.size();i++){
            URLS[i] = dataBeen.get(i).picBig;
        }
        listView.setOnScrollListener(this);
    }
    @Override
    public int getCount() {
        return listDataBeen.size();
    }

    @Override
    public MewsBean.DataBean getItem(int position) {
        return listDataBeen.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHodler hodler;
        if(convertView == null){
            convertView = mInflate.inflate(R.layout.item_layout,null);
            hodler = new ViewHodler();
            hodler.imageView = (ImageView) convertView.findViewById(R.id.iv_icon);
            hodler.tvTitle = (TextView) convertView.findViewById(R.id.tv_title);
            hodler.tvContent = (TextView) convertView.findViewById(R.id.tv_content);
            convertView.setTag(hodler);
        }else{
            hodler = (ViewHodler) convertView.getTag();
        }
        MewsBean.DataBean dataBean = listDataBeen.get(position);
        hodler.imageView.setImageResource(R.mipmap.ic_launcher);
        url = dataBean.picBig;
        hodler.imageView.setTag(url);
//        new ImageLoader().showImageByThread(hodler.imageView,url);
//        new ImageLoader().showImageByAsyncTask(hodler.imageView,url);
//        mImageLoader.showImageByAsyncTask(hodler.imageView,url);
        hodler.tvTitle.setText(dataBean.name);
        hodler.tvContent.setText(dataBean.description);
        return convertView;
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        if(scrollState == SCROLL_STATE_IDLE){
            mImageLoader.loadImages(mStart,mEnd);
        }else{
            //停止所有加载
            mImageLoader.canCellAllTask();
        }
    }
    //第一次进来的时候此方法会调用
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        mStart = firstVisibleItem;
        mEnd = firstVisibleItem + visibleItemCount;
        //初始化调用的时候visibleItemCount=0,此时item还没有加载
        if(isFirstShow&&visibleItemCount>0){
            mImageLoader.loadImages(mStart,mEnd);
            isFirstShow = false;
        }
    }

    public static class ViewHodler{
        public ImageView imageView;
        public TextView tvTitle;
        public TextView tvContent;
    }
}
public class MainActivity extends Activity{
    ListView listview;
    private ListAdapter adapter;
    //这里必须带http的前缀
    public static final String URL = "http://www.imooc.com/api/teacher?type=4&num=30";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listview = (ListView) findViewById(R.id.listview);
        new NewsTask().execute(URL);
    }
    class NewsTask extends AsyncTask>{

        @Override
        protected List doInBackground(String... params) {
            return getJsonData(params[0]);
        }

        @Override
        protected void onPostExecute(List dataBeen) {
            super.onPostExecute(dataBeen);
            NewsAdapter adapter = new NewsAdapter(MainActivity.this,dataBeen,listview);
            listview.setAdapter(adapter);
        }
    }
    public List getJsonData(String url){
        List list = new ArrayList<>();
        try {
            //此句功能与url.openConnection().openInputStream功能相同
            String jsonString = getJsonString(new URL(url).openStream());
            Gson gson = new Gson();
            MewsBean mewsBean = gson.fromJson(jsonString, MewsBean.class);
            for (int i = 0; i < mewsBean.data.size(); i++) {
                list.add(mewsBean.data.get(i));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }

    public String getJsonString(InputStream inputStream){
        String result = "";
        InputStreamReader isr = null;
        try {
            String line = "";
            isr = new InputStreamReader(inputStream,"utf-8");
            BufferedReader reader = new BufferedReader(isr);
            while((line = reader.readLine())!=null){
                result+=line;
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
}

你可能感兴趣的:(Android实现异步加载)