当前位置:操作系统 > 安卓/Android >>

演化理解 Android 异步加载图片

在学习"Android异步加载图像小结"这篇文章时, 发现有些地方没写清楚,我就根据我的理解,把这篇文章的代码重写整理了一遍,下面就是我的整理。

下面测试使用的layout文件:

简单来说就是 LinearLayout 布局,其下放了5个ImageView。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical" android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <TextView android:text="图片区域开始" android:id="@+id/textView2"
  android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
 <ImageView android:id="@+id/imageView1"
  android:layout_height="wrap_content" android:src="@drawable/icon"
  android:layout_width="wrap_content"></ImageView>
 <ImageView android:id="@+id/imageView2"
  android:layout_height="wrap_content" android:src="@drawable/icon"
  android:layout_width="wrap_content"></ImageView>
 <ImageView android:id="@+id/imageView3"
  android:layout_height="wrap_content" android:src="@drawable/icon"
  android:layout_width="wrap_content"></ImageView>
 <ImageView android:id="@+id/imageView4"
  android:layout_height="wrap_content" android:src="@drawable/icon"
  android:layout_width="wrap_content"></ImageView>
 <ImageView android:id="@+id/imageView5"
  android:layout_height="wrap_content" android:src="@drawable/icon"
  android:layout_width="wrap_content"></ImageView>
 <TextView android:text="图片区域结束" android:id="@+id/textView1"
  android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
</LinearLayout>我们将演示的逻辑是异步从服务器上下载5张不同图片,依次放入这5个ImageView。上下2个TextView 是为了方便我们看是否阻塞了UI的显示。

当然 AndroidManifest.xml 文件中要配置好网络访问权限。

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

Handler+Runnable模式
我们先看一个并不是异步线程加载的例子,使用 Handler+Runnable模式。

这里为何不是新开线程的原因请参看这篇文章:Android Runnable 运行在那个线程 这里的代码其实是在UI 主线程中下载图片的,而不是新开线程。

我们运行下面代码时,会发现他其实是阻塞了整个界面的显示,需要所有图片都加载完成后,才能显示界面。

package ghj1976.AndroidTest;

import java.io.IOException;
import java.net.URL;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import android.widget.ImageView;

public class MainActivity extends Activity {
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  loadImage("", R.id.imageView1);
  loadImage(",
    R.id.imageView2);
  loadImage(", R.id.imageView3);
  loadImage("",
    R.id.imageView4);
  loadImage("",
    R.id.imageView5);
 }

 private Handler handler = new Handler();

 private void loadImage(final String url, final int id) {
  handler.post(new Runnable() {
   public void run() {
    Drawable drawable = null;
    try {
     drawable = Drawable.createFromStream(
       new URL(url).openStream(), "image.gif");
    } catch (IOException e) {
     Log.d("test", e.getMessage());
    }
    if (drawable == null) {
     Log.d("test", "null drawable");
    } else {
     Log.d("test", "not null drawable");
    }
                                // 为了测试缓存而模拟的网络延时                                 SystemClock.sleep(2000);     ((ImageView) MainActivity.this.findViewById(id))
      .setImageDrawable(drawable);
   }
  });
 }
}

Handler+Thread+Message模式
这种模式使用了线程,所以可以看到异步加载的效果。

核心代码:

package ghj1976.AndroidTest;

import java.io.IOException;
import java.net.URL;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.widget.ImageView;

public class MainActivity extends Activity {
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  loadImage2("", R.id.imageView1);
  loadImage2("",
    R.id.imageView2);
  loadImage2("", R.id.imageView3);
  loadImage2("",
    R.id.imageView4);
  loadImage2("",
    R.id.imageView5);
 }

 final Handler handler2 = new Handler() {
  @Override
  public void handleMessage(Message msg) {
   ((ImageView) MainActivity.this.findViewById(msg.arg1))
     .setImageDrawable((Drawable) msg.obj);
  }
 };

 // 采用handler+Thread模式实现多线程异步加载
 private void loadImage2(final String url, final int id) {
  Thread thread = new Thread() {
   @Override
   public void run() {
    Drawable drawable = null;
    try {
     drawable = Drawable.createFromStream(
       new URL(url).openStream(), "image.png");
    } catch (IOException e) {
     Log.d("test", e.getMessage());
    }

    // 模拟网络延时
    SystemClock.sleep(2000);

补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,