Handler+thread 加载网络图片

来源:互联网 发布:卖家淘宝店名可以改吗 编辑:程序博客网 时间:2024/05/19 20:48

关于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 plaincopyprint?
  1. package com.study.thread;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.ProgressDialog;  
  5. import android.graphics.Bitmap;  
  6. import android.os.Bundle;  
  7. import android.os.Handler;  
  8. import android.os.Message;  
  9. import android.util.Log;  
  10. import android.view.View;  
  11. import android.view.View.OnClickListener;  
  12. import android.widget.ImageView;  
  13. import android.widget.Toast;  
  14.   
  15. public class ThreadDemo extends Activity {  
  16.     private static final String TAG =  "ThreadDemo";  
  17.     // 我把三个线程编了号  
  18.     private static final int THREAD_1 = 1;  
  19.     private static final int THREAD_2 = 2;  
  20.     private static final int THREAD_3 = 3;  
  21.     private ImageView mImgView1;  
  22.     private ImageView mImgView2;  
  23.     private ImageView mImgView3;  
  24.       
  25.     // 记录消息  
  26.     int count = 0;  
  27.       
  28.     ProgressDialog mDialog ;  
  29.       
  30.     // 网上找的三张图片的地址  
  31.     String[] urls =  new String[]  
  32.             {  
  33.             "http://hiphotos.baidu.com/yuangengqiang/pic/item/252196ca222b88ad50664f58.jpg",  
  34.             "http://hiphotos.baidu.com/lzc196806/pic/item/d84f738da76514d2f11f3665.jpg",  
  35.             "http://hiphotos.baidu.com/735216726/pic/item/2488f146f7ea415e72f05d75.jpg"  
  36.             };  
  37.       
  38.     @Override  
  39.     public void onCreate(Bundle savedInstanceState) {  
  40.         super.onCreate(savedInstanceState);  
  41.         setContentView(R.layout.main);  
  42.         this.getView();  
  43.         System.out.println("ThreadDemo-----"+Thread.currentThread().getName());  
  44.           
  45.         // 处理按钮按下  
  46.         findViewById(R.id.btnStart).setOnClickListener(new OnClickListener()  
  47.         {  
  48.               
  49.             @Override  
  50.             public void onClick(View v)  
  51.             {  
  52.                 count = 0;  
  53.                 mDialog = ProgressDialog.show(ThreadDemo.this"",   
  54.                         "Loading. Please wait..."true);  
  55.                 // 开启线程:第一个线程处理第一张图片以此类推  
  56.                 new Thread(new LoadImageRunnable(mHandler,THREAD_1,urls[0])).start();  
  57.                 new Thread(new LoadImageRunnable(mHandler,THREAD_2,urls[1])).start();  
  58.                 new Thread(new LoadImageRunnable(mHandler,THREAD_3,urls[2])).start();  
  59.                 ThreadDemo.this.setTitle("线程已近创建完毕");  
  60.             }  
  61.               
  62.         });  
  63.     }  
  64.       
  65.     private void getView()  
  66.     {  
  67.         mImgView1 = (ImageView)findViewById(R.id.img01);  
  68.         mImgView2 = (ImageView)findViewById(R.id.img02);  
  69.         mImgView3 = (ImageView)findViewById(R.id.img03);  
  70.     }  
  71.       
  72.       
  73.       
  74.     private Handler mHandler = new Handler()  
  75.     {  
  76.           
  77.         // 利用handleMessage更新UI  
  78.         public void handleMessage (Message msg)  
  79.         {  
  80.             switch(msg.what)  
  81.             {  
  82.                 case ThreadDemo.THREAD_1:  
  83.                     mImgView1.setImageBitmap((Bitmap)msg.obj);  
  84.                     Log.i(TAG, "thread-1");  
  85.                     break;  
  86.                 case ThreadDemo.THREAD_2:  
  87.                     mImgView2.setImageBitmap((Bitmap)msg.obj);  
  88.                     Log.i(TAG, "thread-2");  
  89.                     break;  
  90.                 case ThreadDemo.THREAD_3:  
  91.                     mImgView3.setImageBitmap((Bitmap)msg.obj);  
  92.                     Log.i(TAG, "thread-3");  
  93.                     break;  
  94.                       
  95.                 // 如有异常会有提示  
  96.                 default:  
  97.                     String info = "第"+msg.what%10+"个线程"+"出现异常";  
  98.                     Toast.makeText(ThreadDemo.this, info , Toast.LENGTH_LONG).show();  
  99.                     break;  
  100.               
  101.             }  
  102.             count++;  
  103.             if(3==count)  
  104.             {  
  105.                 mDialog.dismiss();  
  106.             }  
  107.               
  108.         }  
  109.     };  
  110. }  


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

[java] view plaincopyprint?
  1. package com.study.thread;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5. import java.net.MalformedURLException;  
  6. import java.net.URL;  
  7. import java.net.URLConnection;  
  8.   
  9. import android.graphics.Bitmap;  
  10. import android.graphics.BitmapFactory;  
  11. import android.os.Handler;  
  12. import android.os.Message;  
  13. /** 
  14.  * @author manymore13 
  15.  *  
  16.  */  
  17. public class LoadImageRunnable implements Runnable  
  18. {  
  19.   
  20.     private int mThreadId ;  
  21.     private Handler mHandler ;  
  22.     private String sUrl;  
  23.     public LoadImageRunnable(Handler h, int id, String str)  
  24.     {  
  25.         mHandler = h;  
  26.         mThreadId = id;  
  27.         sUrl = str;  
  28.     }  
  29.     @Override  
  30.     public void run()  
  31.     {  
  32.         Message msg = new Message();  
  33.         msg.what = mThreadId;  
  34.         msg.obj = loadImageFromNetwork();  
  35.         mHandler.sendMessage(msg);  
  36.         System.out.println("LoadImageRunnable-----"+Thread.currentThread().getName());  
  37.           
  38.     }  
  39.       
  40.     // 从外部链接加载图片  
  41.     private Bitmap loadImageFromNetwork()  
  42.     {  
  43.         Bitmap bm = null;  
  44.         try  
  45.         {  
  46.             URL url = new URL(sUrl);  
  47.             URLConnection conn = url.openConnection();  
  48.             InputStream is = conn.getInputStream();  
  49.             bm = BitmapFactory.decodeStream(is);   
  50.         }   
  51.         catch (MalformedURLException e){  
  52.               
  53.             e.printStackTrace();  
  54.             mHandler.sendEmptyMessage(10+mThreadId);  
  55.               
  56.         }catch(IOException e)  
  57.          {  
  58.             mHandler.sendEmptyMessage(10+mThreadId);  
  59.             e.printStackTrace();  
  60.          }  
  61.         return bm;  
  62.     }  
  63.   
  64. }  

UI布局

[html] view plaincopyprint?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"   
  4.     android:layout_height="match_parent"  
  5.     android:scrollbars="vertical" >  
  6.               
  7.     <LinearLayout   
  8.         android:orientation="vertical"  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="fill_parent">  
  11.         <TextView    
  12.             android:layout_width="fill_parent"   
  13.             android:layout_height="wrap_content"   
  14.             android:text="@string/hello"  
  15.             android:gravity="center_horizontal"  
  16.             android:layout_marginBottom="5dp"/>  
  17.         <Button  
  18.             android:id="@+id/btnStart"  
  19.             android:layout_width="200dp"  
  20.             android:layout_height="wrap_content"  
  21.             android:background="@drawable/button_bg"  
  22.             android:text="开始做事"  
  23.             android:layout_gravity="center_horizontal"  
  24.             android:layout_marginBottom="10dp"/>  
  25.         <ImageView  
  26.             android:id="@+id/img01"  
  27.             android:layout_width="match_parent"  
  28.             android:layout_height="200dp"  
  29.             android:layout_marginBottom="5dp"/>  
  30.         <ImageView  
  31.             android:id="@+id/img02"  
  32.             android:layout_width="match_parent"  
  33.             android:layout_height="200dp"  
  34.             android:layout_marginBottom="5dp"/>  
  35.         <ImageView  
  36.             android:id="@+id/img03"  
  37.             android:layout_width="match_parent"  
  38.             android:layout_height="200dp"/>  
  39.                           
  40.     </LinearLayout>  
  41.       
  42. </ScrollView>  

下面是运行后效果图:

第一次测试:


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


第二次测试:

 

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


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

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

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

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

下载 handler结合Thread异步加载网络图片  有什么建议欢迎提出来!

这次学习笔记到此为止!睡觉

0 0
原创粉丝点击