Handler+thread 加载网络图片

 本文来自 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在这里面更新

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 线程处理的事都在这里面

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布局

<?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>

下面是运行后效果图:

第一次测试:

Handler+thread 加载网络图片_第1张图片Handler+thread 加载网络图片_第2张图片

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


第二次测试:

Handler+thread 加载网络图片_第3张图片 

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


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

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

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

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

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

这次学习笔记到此为止!

你可能感兴趣的:(thread,android,网络,String,layout)