您的位置:首页 > 理论基础 > 计算机网络

Handler+thread 加载网络图片

2016-05-10 17:46 471 查看
本文来自 http://blog.csdn.net/manymore13 

关于Android多线程处理UI-我在网上查了下资料发现有好几种,本次学习只是其中一种,主要是利用handler结合Thread更新UI。

下面是我写的小Demo:

            Handler+thread 加载网络图片,我在网上随便找了三张图片,分别开三个线程加载他们,然后在Activity中显示。

            其中一个线程出现异常不会影响到其他线程更不会阻塞主线程(UI线程) ,这是多线程带来的好处之一。


本次Demo主要是利用Handler.sendMessage(...)把消息压进消息队列,过后通过Handler.handleMessage(...)在UI线程中处理压入的消

息。从队列中取出消息时会根据压入的不同消息来更新UI。图片在外部线程中加载,加载完后sendmessage在主线程中更新UI。外

部线程只顾加载图片,而更新UI是主线程(UI线程)的事,这个就达到了多线程异步加载网络图片的目的

ThreadDemo.java   ThreadDemo是一个Activity,UI在这里面更新

[java] view
plain copy

 print?

package com.study.thread;  

  

import android.app.Activity;  

import android.app.ProgressDialog;  

import android.graphics.Bitmap;  

import android.os.Bundle;  

import android.os.Handler;  

import android.os.Message;  

import android.util.Log;  

import android.view.View;  

import android.view.View.OnClickListener;  

import android.widget.ImageView;  

import android.widget.Toast;  

  

public class ThreadDemo extends Activity {  

    private static final String TAG =  "ThreadDemo";  

    // 我把三个线程编了号  

    private static final int THREAD_1 = 1;  

    private static final int THREAD_2 = 2;  

    private static final int THREAD_3 = 3;  

    private ImageView mImgView1;  

    private ImageView mImgView2;  

    private ImageView mImgView3;  

      

    // 记录消息  

    int count = 0;  

      

    ProgressDialog mDialog ;  

      

    // 网上找的三张图片的地址  

    String[] urls =  new String[]  

            {  

            "http://hiphotos.baidu.com/yuangengqiang/pic/item/252196ca222b88ad50664f58.jpg",  

            "http://hiphotos.baidu.com/lzc196806/pic/item/d84f738da76514d2f11f3665.jpg",  

            "http://hiphotos.baidu.com/735216726/pic/item/2488f146f7ea415e72f05d75.jpg"  

            };  

      

    @Override  

    public void onCreate(Bundle savedInstanceState) {  

        super.onCreate(savedInstanceState);  

        setContentView(R.layout.main);  

        this.getView();  

        System.out.println("ThreadDemo-----"+Thread.currentThread().getName());  

          

        // 处理按钮按下  

        findViewById(R.id.btnStart).setOnClickListener(new OnClickListener()  

        {  

              

            @Override  

            public void onClick(View v)  

            {  

                count = 0;  

                mDialog = ProgressDialog.show(ThreadDemo.this, "",   

                        "Loading. Please wait...", true);  

                // 开启线程:第一个线程处理第一张图片以此类推  

                new Thread(new LoadImageRunnable(mHandler,THREAD_1,urls[0])).start();  

                new Thread(new LoadImageRunnable(mHandler,THREAD_2,urls[1])).start();  

                new Thread(new LoadImageRunnable(mHandler,THREAD_3,urls[2])).start();  

                ThreadDemo.this.setTitle("线程已近创建完毕");  

            }  

              

        });  

    }  

      

    private void getView()  

    {  

        mImgView1 = (ImageView)findViewById(R.id.img01);  

        mImgView2 = (ImageView)findViewById(R.id.img02);  

        mImgView3 = (ImageView)findViewById(R.id.img03);  

    }  

      

      

      

    private Handler mHandler = new Handler()  

    {  

          

        // 利用handleMessage更新UI  

        public void handleMessage (Message msg)  

        {  

            switch(msg.what)  

            {  

                case ThreadDemo.THREAD_1:  

                    mImgView1.setImageBitmap((Bitmap)msg.obj);  

                    Log.i(TAG, "thread-1");  

                    break;  

                case ThreadDemo.THREAD_2:  

                    mImgView2.setImageBitmap((Bitmap)msg.obj);  

                    Log.i(TAG, "thread-2");  

                    break;  

                case ThreadDemo.THREAD_3:  

                    mImgView3.setImageBitmap((Bitmap)msg.obj);  

                    Log.i(TAG, "thread-3");  

                    break;  

                      

                // 如有异常会有提示  

                default:  

                    String info = "第"+msg.what%10+"个线程"+"出现异常";  

                    Toast.makeText(ThreadDemo.this, info , Toast.LENGTH_LONG).show();  

                    break;  

              

            }  

            count++;  

            if(3==count)  

            {  

                mDialog.dismiss();  

            }  

              

        }  

    };  

}  

LoadImageRunnable.java 线程处理的事都在这里面

[java] view
plain copy

 print?

package com.study.thread;  

  

import java.io.IOException;  

import java.io.InputStream;  

import java.net.MalformedURLException;  

import java.net.URL;  

import java.net.URLConnection;  

  

import android.graphics.Bitmap;  

import android.graphics.BitmapFactory;  

import android.os.Handler;  

import android.os.Message;  

/** 

 * @author manymore13 

 *  

 */  

public class LoadImageRunnable implements Runnable  

{  

  

    private int mThreadId ;  

    private Handler mHandler ;  

    private String sUrl;  

    public LoadImageRunnable(Handler h, int id, String str)  

    {  

        mHandler = h;  

        mThreadId = id;  

        sUrl = str;  

    }  

    @Override  

    public void run()  

    {  

        Message msg = new Message();  

        msg.what = mThreadId;  

        msg.obj = loadImageFromNetwork();  

        mHandler.sendMessage(msg);  

        System.out.println("LoadImageRunnable-----"+Thread.currentThread().getName());  

          

    }  

      

    // 从外部链接加载图片  

    private Bitmap loadImageFromNetwork()  

    {  

        Bitmap bm = null;  

        try  

        {  

            URL url = new URL(sUrl);  

            URLConnection conn = url.openConnection();  

            InputStream is = conn.getInputStream();  

            bm = BitmapFactory.decodeStream(is);   

        }   

        catch (MalformedURLException e){  

              

            e.printStackTrace();  

            mHandler.sendEmptyMessage(10+mThreadId);  

              

        }catch(IOException e)  

         {  

            mHandler.sendEmptyMessage(10+mThreadId);  

            e.printStackTrace();  

         }  

        return bm;  

    }  

  

}  

UI布局

[html] view
plain copy

 print?

<?xml version="1.0" encoding="utf-8"?>  

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"  

    android:layout_width="match_parent"   

    android:layout_height="match_parent"  

    android:scrollbars="vertical" >  

              

    <LinearLayout   

        android:orientation="vertical"  

        android:layout_width="fill_parent"  

        android:layout_height="fill_parent">  

        <TextView    

            android:layout_width="fill_parent"   

            android:layout_height="wrap_content"   

            android:text="@string/hello"  

            android:gravity="center_horizontal"  

            android:layout_marginBottom="5dp"/>  

        <Button  

            android:id="@+id/btnStart"  

            android:layout_width="200dp"  

            android:layout_height="wrap_content"  

            android:background="@drawable/button_bg"  

            android:text="开始做事"  

            android:layout_gravity="center_horizontal"  

            android:layout_marginBottom="10dp"/>  

        <ImageView  

            android:id="@+id/img01"  

            android:layout_width="match_parent"  

            android:layout_height="200dp"  

            android:layout_marginBottom="5dp"/>  

        <ImageView  

            android:id="@+id/img02"  

            android:layout_width="match_parent"  

            android:layout_height="200dp"  

            android:layout_marginBottom="5dp"/>  

        <ImageView  

            android:id="@+id/img03"  

            android:layout_width="match_parent"  

            android:layout_height="200dp"/>  

                          

    </LinearLayout>  

      

</ScrollView>  

下面是运行后效果图:

第一次测试:





             图一 : 按下按钮后 在加载图片,请稍后                                                       图二 :加载完毕 三张图片都显示出来

第二次测试:




 

  图三:我故意把第二张图片地址给改错了,加载时出现异常                 图四:加载完毕 没有出现第二张图片

       我在网上找的几张图片相对于手机屏幕来说其实是很大的,但是加载手机屏幕上就变

小了,原因是我在布局时设置了ImageView的高度,另外我没有设置水平滚动条,其实图片是可以不被缩小的显示在屏

幕上。解决方法很简单,把整个Activity设置成同时拥有水平和垂直滚动条就可以搞定。OK,解决方

法可以参考我的另外一篇文章 实现一个Activity存在水平和垂直滚动条 
  

下载 handler结合Thread异步加载网络图片  有什么建议欢迎提出来!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  线程 android