• 使用异步任务加载网络上的图片


      我们知道,如果要加载一个很耗时的操作,会阻塞主线程,这时我们可以想到开启一个新的线程,避免阻塞,在android中也有这样的问题,我们可以用异步任务来操作,异步任务也是开启一个线程,线程里面发一个消息,然后通知去改变UI。

      废话不多说,我们先看一个例子:我们可以打开这个网址:http://img1.3lian.com/img2011/07/20/05.jpg可以看到一副很好看的图片,我们就要把这个图片显示出来,首先,还是先要布局,我们要显示一幅图片,所以我们的布局中需要一个ImageView,布局很简单,一个ImageView就可以了:

      

     1 <?xml version="1.0" encoding="utf-8"?>
    2 <LinearLayout
    3 xmlns:android="http://schemas.android.com/apk/res/android"
    4 android:layout_width="match_parent"
    5 android:layout_height="match_parent">
    6 <ImageView
    7 android:id="@+id/img"
    8 android:scaleType="fitXY"
    9 android:layout_width="match_parent"
    10 android:layout_height="match_parent"/>
    11 </LinearLayout>

     之后我们要写一个Activity显示这个图片,不过要加载网络上的图片,我们需要从一个URL的流中获取这个图片,所以我们要写一个方法来获取这张图片:

      

    1 public Drawable loadImages(String url) { 
    2 try {
    3 return Drawable.createFromStream((InputStream)(new URL(url)).openStream(), "test");
    4 }
    5 catch (IOException e) {
    6 e.printStackTrace();
    7 }
    8 return null;
    9 }

      从URL中打开流,强制转换成InputStream,然后从流中拿到Drawable。

      既然可以获取图片了,我们要考虑一个问题,如果图片很大,加载的很慢怎么办,我们岂不是要等很久?不要紧,这时候我们就可以用异步任务了。

      首先我们要写一个内部类,这个类部类是继承自异步任务的,需要重载里面的doBackGround方法:

      

     1  private class ImageAsynTask extends AsyncTask<Void, Void, Drawable> {
    2
    3 @Override
    4 protected Drawable doInBackground (Void... params) {
    5 String url = "http://img1.3lian.com/img2011/07/20/05.jpg";
    6 return loadImages(url);
    7 }
    8
    9 @Override
    10 protected void onPostExecute (Drawable result) {
    11 super.onPostExecute(result);
    12 mDialog.dismiss();
    13 mImage.setImageDrawable(result);
    14 }
    15
    16 @Override
    17 protected void onPreExecute () {
    18 super.onPreExecute();
    19 mDialog.show();
    20 }
    21 }

     首先看这个方法:onPreExecute()这个方法是在doInBackGround前面执行。我们把这个方法写出来,我们需要在获取图片之前等待的时间里,写一个progressDialog,显示出来,提示用户,目前正在加载图片,需要等待一段时间。同时在后台操作doBackGround运行。

      在doBackGround完成之后就会执行onPostExecute(Drawable result)方法,看这个方法就知道,必须在doBackGround完成之后,把得到的结果Drawable作为参数传到onPostExecute方法里面去,执行这个方法就表示已经加载完了,我们需要将progressDialog消失掉,然后把图片显示出来就可以了,整个过程很简单。

      看下整个Activity的代码:

      

     1 package com.test.asyntask;
    2
    3 import java.io.IOException;
    4 import java.io.InputStream;
    5 import java.net.URL;
    6
    7 import android.app.Activity;
    8 import android.app.ProgressDialog;
    9 import android.graphics.drawable.Drawable;
    10 import android.os.AsyncTask;
    11 import android.os.Bundle;
    12 import android.widget.ImageView;
    13
    14 import com.test.R;
    15
    16 public class AsynTask extends Activity {
    17
    18 private ImageView mImage;
    19 private ProgressDialog mDialog;
    20
    21 @Override
    22 protected void onCreate (Bundle savedInstanceState) {
    23 super.onCreate(savedInstanceState);
    24 setContentView(R.layout.asyn_task);
    25
    26 mDialog = new ProgressDialog(this);
    27 mDialog.setTitle("请稍等");
    28 mDialog.setMessage("正在加载...");
    29
    30 mImage = (ImageView) findViewById(R.id.img);
    31 new ImageAsynTask().execute();
    32 }
    33
    34 private class ImageAsynTask extends AsyncTask<Void, Void, Drawable> {
    35
    36 @Override
    37 protected Drawable doInBackground (Void... params) {
    38 String url = "http://img1.3lian.com/img2011/07/20/05.jpg";
    39 return loadImages(url);
    40 }
    41
    42 @Override
    43 protected void onPostExecute (Drawable result) {
    44 super.onPostExecute(result);
    45 mDialog.dismiss();
    46 mImage.setImageDrawable(result);
    47 }
    48
    49 @Override
    50 protected void onPreExecute () {
    51 super.onPreExecute();
    52 mDialog.show();
    53 }
    54 }
    55
    56 @Override
    57 protected void onDestroy () {
    58 super.onDestroy();
    59 mDialog.dismiss();
    60 }
    61
    62 public Drawable loadImages(String url) {
    63 try {
    64 return Drawable.createFromStream((InputStream)(new URL(url)).openStream(), "test");
    65 }
    66 catch (IOException e) {
    67 e.printStackTrace();
    68 }
    69 return null;
    70 }
    71 }

     运行一下,看下效果:

      1.显示progressDialog的时候,在加载图片但是图片还没有加载出来的时候:

      

      2.看一下显示出来的图片吧:

      

     可以看到,加载完成后,图片可以显示出来了。

      另外需要注意的是,需要在manifest里面加入链接网络的权限:

      

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

      另外在onDestory()的时候要把progressDialog dismiss掉,不让在退出应用程序的时候会报错。

      好了就到这儿吧,外面打很大的雷,估计下雨了吧,我还没带伞呢,哎,又得淋雨回去了啊。。。。悲惨啊。。。

      哦,对了,把源代码传上来吧,里面的内容很多,都是写的例子程序,在com.test.asyntask包里面。

      点击我下载

  • 相关阅读:
    linux内核数据包转发流程(三)网卡帧接收分析
    StringTokenizer类的使用
    提问的艺术(中文版)
    编写ruby扩展库
    java.lang.Math中的基本方法
    CocoStudio学习资源
    数据流图的画法
    UVa 11069
    PHP之运用CI用钩子实现URL权限控制————————【Badboy】
    [ACM] POJ 3686 The Windy&#39;s (二分图最小权匹配,KM算法,特殊建图)
  • 原文地址:https://www.cnblogs.com/shang53880/p/2124146.html
Copyright © 2020-2023  润新知