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在这里面更新
- 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()
- {
-
-
- 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;
-
-
-
-
- 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>
下面是运行后效果图:第一次测试:
图一 : 按下按钮后 在加载图片,请稍后 图二 :加载完毕 三张图片都显示出来
第二次测试:
图三:我故意把第二张图片地址给改错了,加载时出现异常 图四:加载完毕 没有出现第二张图片
我在网上找的几张图片相对于手机屏幕来说其实是很大的,但是加载手机屏幕上就变
小了,原因是我在布局时设置了ImageView的高度,另外我没有设置水平滚动条,其实图片是可以不被缩小的显示在屏
幕上。解决方法很简单,把整个Activity设置成同时拥有水平和垂直滚动条就可以搞定。OK,解决方
法可以参考我的另外一篇文章 实现一个Activity存在水平和垂直滚动条
下载 handler结合Thread异步加载网络图片 有什么建议欢迎提出来!
这次学习笔记到此为止!
0 0