5

私は初心者プログラマーで、特定の URL から ImageView に画像を表示する Android プログラムを作成しています。私の問題は、これを AsyncTask でどのように使用するかです。

これらのコードは最小 SDK 2.2 で動作しますが、最小 SDK 3.0 に切り替えたので、AsyncTask で実行する必要があります。ご協力ありがとうございました!:)

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    satellite(); //satellite's image from main menu

}

//******satellite url
private void satellite() {
    // TODO Auto-generated method stub
    ImageView imgView =(ImageView)findViewById(R.id.satellite);
    Drawable drawable = LoadImageFromWeb("http://www.pagasa.dost.gov.ph/wb/sat_images/satellite.gif");
    imgView.setImageDrawable(drawable);        
}

private Drawable LoadImageFromWeb(String url){
      try{
          InputStream is = (InputStream) new URL(url).getContent();
          Drawable d = Drawable.createFromStream(is, "src name");
          return d;
      }catch (Exception e) {
          System.out.println("Exc="+e);
          return null;
      }
}
4

7 に答える 7

3

Android SDK がそれをサポートしていない理由はわかりません (まだ)、非同期の読み込みとキャッシュのサポートを使用して、UrlImageView クラスによって ImageView クラスを拡張しました。プラグアンドプレイであるクラスのコードを以下に示します。クラス本体は私の投稿の最後にあり、便利な方法で使用する方法を 2 行書きます。

さらに 2 つの方法がサポートされるようになりました。

setImageUrl(URL url) // sets the bitmap by its URL
cancelLoading();     // tell this view to cancel pending load

Java コードの使用方法:

// [somewhere in your activity]
UrlImageView urlImg = new UrlImageView(this).setImageUrl("http://abc.png");
...
urlImg.setImageUrl("http://abc2.png"); // works like expected

レイアウトにバインドする方法:

<!-- thumbnail -->
<com.gplushub.android.view.UrlImageView
    android:id="@+id/thumbnail"
    android:layout_width="64dp"
    android:layout_height="64dp"
    android:layout_gravity="center_vertical"
    android:layout_marginRight="2dp"
    android:scaleType="fitXY" />

..そして再びあなたのアクティビティJavaコードで:

((UrlImageView)findViewById(R.id.thumbnail)).setImageUrl("http://foo.bar.png");

私はそれを 100 を超えるエントリを持つリストで使用します。ここにクラス本体があり、好きなように使用、変更、拡張できます。

package com.gplushub.android.view;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;

/**
 * an {@link ImageView} supporting asynchronous loading from URL. Additional
 * APIs: {@link #setImageURL(URL)}, {@link #cancelLoading()}.
 * 
 * @author ep@gplushub.com / Eugen Plischke
 * 
 */
public class UrlImageView extends ImageView {
  private static class UrlLoadingTask extends AsyncTask<URL, Void, Bitmap> {
    private final ImageView updateView;
    private boolean         isCancelled = false;
    private InputStream     urlInputStream;

    private UrlLoadingTask(ImageView updateView) {
      this.updateView = updateView;
    }

    @Override
    protected Bitmap doInBackground(URL... params) {
      try {
        URLConnection con = params[0].openConnection();
        // can use some more params, i.e. caching directory etc
        con.setUseCaches(true);
        this.urlInputStream = con.getInputStream();
        return BitmapFactory.decodeStream(urlInputStream);
      } catch (IOException e) {
        Log.w(UrlImageView.class.getName(), "failed to load image from " + params[0], e);
        return null;
      } finally {
        if (this.urlInputStream != null) {
          try {
            this.urlInputStream.close();
          } catch (IOException e) {
            ; // swallow
          } finally {
            this.urlInputStream = null;
          }
        }
      }
    }

    @Override
    protected void onPostExecute(Bitmap result) {
      if (!this.isCancelled) {
        // hope that call is thread-safe
        this.updateView.setImageBitmap(result);
      }
    }

    /*
     * just remember that we were cancelled, no synchronization necessary
     */
    @Override
    protected void onCancelled() {
      this.isCancelled = true;
      try {
        if (this.urlInputStream != null) {
          try {
            this.urlInputStream.close();
          } catch (IOException e) {
            ;// swallow
          } finally {
            this.urlInputStream = null;
          }
        }
      } finally {
        super.onCancelled();
      }
    }
  }

  /*
   * track loading task to cancel it
   */
  private AsyncTask<URL, Void, Bitmap> currentLoadingTask;
  /*
   * just for sync
   */
  private Object                       loadingMonitor = new Object();

  public UrlImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  public UrlImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public UrlImageView(Context context) {
    super(context);
  }

  @Override
  public void setImageBitmap(Bitmap bm) {
    cancelLoading();
    super.setImageBitmap(bm);
  }

  @Override
  public void setImageDrawable(Drawable drawable) {
    cancelLoading();
    super.setImageDrawable(drawable);
  }

  @Override
  public void setImageResource(int resId) {
    cancelLoading();
    super.setImageResource(resId);
  }

  @Override
  public void setImageURI(Uri uri) {
    cancelLoading();
    super.setImageURI(uri);
  }

  /**
   * loads image from given url
   * 
   * @param url
   */
  public void setImageURL(URL url) {
    synchronized (loadingMonitor) {
      cancelLoading();
      this.currentLoadingTask = new UrlLoadingTask(this).execute(url);
    }
  }

  /**
   * cancels pending image loading
   */
  public void cancelLoading() {
    synchronized (loadingMonitor) {
      if (this.currentLoadingTask != null) {
        this.currentLoadingTask.cancel(true);
        this.currentLoadingTask = null;
      }
    }
  }
}
于 2013-04-03T20:57:20.747 に答える
2

画像がそれほど大きくない場合は、非同期タスクに匿名クラスを使用できます。これはこれを望みます:

ImageView mChart = (ImageView) findViewById(R.id.imageview);
String URL = "http://www...anything ...";

mChart.setTag(URL);
new DownloadImageTask.execute(mChart);

タスククラスは

public class DownloadImagesTask extends AsyncTask<ImageView, Void, Bitmap> {
   ImageView imageView = null;
   @Override
   protected Bitmap doInBackground(ImageView... imageViews) {
      this.imageView = imageViews[0];
      return download_Image((String)imageView.getTag());
   }

   @Override
   protected void onPostExecute(Bitmap result) {
      imageView.setImageBitmap(result);
   }

   private Bitmap download_Image(String url) {
       ...
   }
于 2013-01-15T06:38:43.943 に答える
1

このコードを試して、ドローアブル変数をグローバルにし、サテライト関数を次のように変更します。

private void satellite() {
      // TODO Auto-generated method stub
      ImageView imgView =(ImageView)findViewById(R.id.satellite);
      new yourTask().execute();
}

次に、次のように asyncTask クラスを作成します。

private class yourTask extends AsyncTask<Integer, Void, Integer> {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        //show a progress bar
    }

    @Override
    protected String doInBackground(Integer... params) {
        drawable  =  LoadImageFromWeb("http://www.pagasa.dost.gov.ph/wb/sat_images/satellite.gif"); 
        return 0; 
    }      

    @Override
    protected void onPostExecute(Integer result) {
        super.onPostExecute(result);
        imgView.setImageDrawable(drawable);   
    }
}
于 2013-01-15T06:51:35.957 に答える
0

後でネットワーク操作を行うときは正しいですAsynctaskAndroid 2.2(Froyo)を使用する必要があります

これは理解するための最良の例ですAsyncTask

于 2013-01-15T06:44:16.940 に答える
0

次のような新しいクラス「DownloadImageTask 」を作成し、 Activityと同じフォルダーに配置します。

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.widget.ImageView;
import android.os.AsyncTask;
import java.io.*;


public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    ImageView bmImage;

    public DownloadImageTask(ImageView bmImage) {
        this.bmImage = bmImage;
    }

    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap myImage = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            myImage = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return myImage;
    }

    protected void onPostExecute(Bitmap result) {
        bmImage.setImageBitmap(result);
    }
}

この後、 Activityでそのクラスをクレートする行を追加します。

import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.util.Log;
import android.widget.ImageView;


public class HomeScreen extends ActionBarActivity {

    private final String TAG = "test1";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate");
        setContentView(R.layout.activity_home_screen);
        InitHomeScreen();
    }

    protected void InitHomeScreen()
    {
        String imageUrl = "http://s20.postimg.org/4t9w2pdct/logo_android_png.png";
        Log.d(TAG, "Get an Image");
        // Get an Image
        try{
            AsyncTask<String, Void, Bitmap> execute = new DownloadImageTask((ImageView) findViewById(R.id.imageView))
                    .execute(imageUrl);
              // R.id.imageView  -> Here imageView is id of your ImageView
        }
        catch(Exception ex)
        {
        }
    }

   // Other code...

Android アプリにインターネットへのアクセスを許可することを忘れないでください。

マニフェスト ファイルを確認します。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.dmitry.myapplication1" >

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".HomeScreen"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
于 2015-03-16T14:10:34.520 に答える
0

Aynctask 実装のコードは次のとおりです。ドローアブル オブジェクトを Aynctask クラスでグローバルにします。

Class MyDownloader extends AsyncTask<Void,Void,String>{

    Drawable drawable;    
    @Override
    public String doInBackground(Void... args){

        drawable = LoadImageFromWeb("http://www.pagasa.dost.gov.ph/wb/sat_images/satellite.gif");
        return null; // here you can pass any string on response as on error or on success

    }

    public void onPostExecute(String result){

        if(drawable!=null){

            imgView.setImageDrawable(drawable);

        }

    }

}

このクラスのオブジェクトを作成して実行します

private void satellite() {
    // TODO Auto-generated method stub
  ImageView imgView =(ImageView)findViewById(R.id.satellite);
  new MyDownloader.execute();

}

これは、画像をキャッシュするための良い例のリンクです。このリンクと例を確認してください

https://github.com/novoda/ImageLoader

于 2013-01-15T06:42:00.960 に答える