多线程和异步下载图片

一开始从慕课网学习到的异步加载显示图片,今天终于有时间按照记忆写了份异步加载图片代码;有很多小细节需要注意的。
步骤:
   1、先解析完JSon数据,并存放在List中间
   2、异步下载图片,放在Item.xml中
   3、listView.setAdapter(teacherAapter);
  • 1、从类开始介绍:

    • Teacher:图片bean
    • TeacherAdapter:适配器
    • ImageLoad:根据URL获取图片,显示到Item.xml中
    • MainActivity:从Json中获取数据,调用适配器,并显示;
  • 2、解析Json

    • 通过Thread来适配
public  void getTeacher()
    {
        new Thread()
        {
            @Override
            public void run() {

                try
                {
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder()
                            .url("http://www.imooc.com/api/teacher?type=4&num=30")
                            .build();
                    Response response = client.newCall(request).execute();
                    String data = response.body().string();
                    parseJson(data);
                    //初始化适配器和列表
                    final TeacherAapter teacherAapter = new TeacherAapter(MainActivity.this,teacherList);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                        //在子线程中设置界面 
                            listView.setAdapter(teacherAapter);
                        }
                    });
                }catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        }.start();
    }
    //解析Json
    public  void parseJson(String data)
    {
        try
        {
            JSONObject jsonObject1 = new JSONObject(data);
            JSONArray jsonArray = jsonObject1.getJSONArray("data");
            System.out.println("length:"+jsonArray.length());
            for(int i=0;i<jsonArray.length();i++)
            {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                Teacher teacher = new Teacher();
                teacher.setName(jsonObject.getString("name"));
                Log.d("name:",jsonObject.getString("name"));
                teacher.setPicSmall(jsonObject.getString("picSmall"));
                teacher.setDescription(jsonObject.getString("description"));
                teacherList.add(teacher);
                System.out.println("tea_list:"+teacherList.size());
            }
        }catch (Exception e)
        {
            e.printStackTrace();
        }
    }
  • AsyncTask 异步加载来适配
class MyAsyncTask extends AsyncTask<String,Void,List<Teacher>>
    {
        @Override
        protected List<Teacher> doInBackground(String... params) {

            teacherList = getTeacher(params[0]);
            return teacherList;
        }

        @Override
        protected void onPostExecute(List<Teacher> teacherList) {
            super.onPostExecute(teacherList);
            TeacherAapter teacherAapter = new TeacherAapter(MainActivity.this,teacherList);
            listView.setAdapter(teacherAapter);
        }
    }
//调用异步任务
new MyAsyncTask().execute(url);
  • 3、加载图片
    • 通过Thread加载
 Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
//            通过判断加载的路径是否正确来加载图片,
            if (imageView.getTag().equals(url))
                imageView.setImageBitmap((Bitmap) msg.obj);
        }
    };
public void showImageByThread(ImageView imageView, final String url) {

        this.url = url;
        this.imageView = imageView;
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Bitmap bitmap = getFromCache(url);
                    if (bitmap == null) {
                        URL url1 = new URL(url);
                        HttpURLConnection connection = (HttpURLConnection) url1.openConnection();
                        InputStream is = connection.getInputStream();
                        bitmap = BitmapFactory.decodeStream(is);
                        is.close();

                        //加入缓存
                        addToCache(url, bitmap);
                    }
//                    OkHttpClient client = new OkHttpClient();
//                    Request request = new Request.Builder()
//                            .url(url)
//                            .build();
//                    Response response = client.newCall(request).execute();
//                    byte[] b =response.body().string().getBytes();
//                    System.out.println("b.length"+b.length);
//                    bitmap = BitmapFactory.decodeByteArray(b,0,b.length);
                    Message message = handler.obtainMessage();
                    message.obj = bitmap;
                    handler.sendMessage(message);

                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }).start();
    }
  • 通过异步加载图片
//通过异步的方法加载
    public void showImageByAsy(ImageView imageView, final String url) {
        this.url = url;
        this.imageView = imageView;
        new MyAsyLoad().execute(url);
    }


    class MyAsyLoad extends AsyncTask<String, Void, Bitmap> {
        @Override
        protected Bitmap doInBackground(String... params) {
            Bitmap bitmap = getFromCache(params[0]);
            if (bitmap != null)
                return bitmap;
            try {
                URL url1 = new URL(params[0]);
                HttpURLConnection connection = (HttpURLConnection) url1.openConnection();
                InputStream is = connection.getInputStream();
                bitmap = BitmapFactory.decodeStream(is);
                is.close();
                addToCache(params[0], bitmap);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return bitmap;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (bitmap != null && imageView != null)
                imageView.setImageBitmap(bitmap);
        }
    }
  • 4、Lrucache缓存
private LruCache<String, Bitmap> mCache;

    public ImageLoad() {
        int maxMemory = (int) Runtime.getRuntime().maxMemory();
        int cacheSize = maxMemory / 8;
        // 设置图片缓存大小为程序最大可用内存的1/8
        mCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                return bitmap.getByteCount();
            }
        };
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
假设我们有一个需求,需要从多个URL地址下载图片并保存到本地。在这种情况下,可以使用多线程和异步I/O来实现高效的下载。 首先,我们可以使用多线程来同时下载多个图片。每个线程都负责下载一个图片,并将其保存到本地。这样可以提高下载效率。以下是使用Python的线程池实现的示例代码: ```python import requests import os from concurrent.futures import ThreadPoolExecutor def download_image(url): response = requests.get(url) filename = os.path.basename(url) with open(filename, 'wb') as f: f.write(response.content) urls = ['http://example.com/image1.jpg', 'http://example.com/image2.jpg', 'http://example.com/image3.jpg'] with ThreadPoolExecutor(max_workers=3) as executor: executor.map(download_image, urls) ``` 上述代码中,我们使用了`ThreadPoolExecutor`来创建一个包含三个线程的线程池。然后,我们使用`executor.map`方法来将下载函数`download_image`和URL列表`urls`传递给线程池进行执行。 但是,在上述代码中,每个线程在下载图片时会阻塞,直到下载任务完成。这可能会导致程序在下载大量图片时变得很慢。因此,我们可以使用异步I/O来避免这种情况。 以下是使用Python的异步I/O库`asyncio`实现的示例代码: ```python import asyncio import aiohttp import os async def download_image(url): async with aiohttp.ClientSession() as session: async with session.get(url) as response: filename = os.path.basename(url) with open(filename, 'wb') as f: while True: chunk = await response.content.read(1024) if not chunk: break f.write(chunk) urls = ['http://example.com/image1.jpg', 'http://example.com/image2.jpg', 'http://example.com/image3.jpg'] loop = asyncio.get_event_loop() tasks = [download_image(url) for url in urls] loop.run_until_complete(asyncio.gather(*tasks)) ``` 在上述代码中,我们使用`asyncio`和`aiohttp`库来创建异步下载函数`download_image`。我们使用`aiohttp.ClientSession`对象来发起HTTP请求,并使用异步循环读取响应内容。 然后,我们使用异步循环`asyncio.get_event_loop()`来运行异步任务。我们使用`asyncio.gather`方法来并发运行所有下载任务,并等待它们完成。这样,我们就可以高效地下载多个图片了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值