0

私はAndroid開発に比較的慣れておらず、ImageViewとTextViewを使用してカスタムListViewを作成しようとしています。URLをビットマップ画像に変換してから、その画像をimageViewに表示しようとしています。ただし、エラーが発生し、アプリケーションがすぐにクラッシュします。imageViewでドローアブルを表示できました。いくつかの変更を加えてビットマップを表示しようとすると、アプリケーションがクラッシュしました。どんな助けでも大歓迎です。これが私の3つのクラスです:

編集非同期タスクを使用して別のスレッドでビットマップイメージを取得しましたが、アプリがクラッシュしなくなりました。ただし、アクティビティを開始するとリストビューが表示されません。これが私の更新されたコードです。

編集コードを再度変更しましたが、非同期タスクのexecuteメソッドでimageViewのみを渡しています。リストビューにテキストを表示できるようになりましたが、画像が表示されません。これが私の編集したコードです。

編集デバッガーを使用して、ビットマップが表示されなかった理由を調べ、ビットマップ変数がnullであることがわかりました。これは、インターネットのアクセス許可を追加していなかったためです。権限を追加した後、私のアプリは指定された行でクラッシュし始めました:

 b = BitmapFactory.decodeStream(image_url.openConnection() .getInputStream());

OutofMemoryエラーが原因でRuntimeExceptionが発生しました。これを解決する方法がわかりません。助けていただければ幸いです。ありがとう !

これが私のLoadimageAsyncTaskクラスです。

 public class LoadImage extends AsyncTask<String, Integer, Bitmap>{

    Context callingContext = null;
    Bitmap b = null;

    ImageView view;

    public LoadImage(ImageView view){

        this.view = view;
    }

    @Override
    protected Bitmap doInBackground(String... arg0) {
        // TODO Auto-generated method stub
        String p_url = "http://java.sogeti.nl/JavaBlog/wp-content/uploads/2009/04/android_icon_256.png";

        Bitmap b = null;
        try {
            URL image_url = new URL(p_url);
            b = BitmapFactory.decodeStream(image_url.openConnection() .getInputStream());

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return b;
    }



    @Override
    protected void onPostExecute(Bitmap result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        view.setImageBitmap(result);

    }   
}
4

1 に答える 1

2

ストリクトモードでUIスレッドのサーバーから画像ファイルを読み込んでいるため、コードがクラッシュしています。画像のダウンロードに時間がかかるとアプリがロックされたように見えるため、これは一般的に悪い習慣と見なされます。

厳密モードはクラッシュを強制します(例外をスローします)。厳密モードを無効にすると、アプリが正常に機能するようになります。ただし、UIスレッドでネットワークI/Oを実行する際の問題は残ります。

より良い長期的な解決策は、AsyncTaskのようなものを使用することです。これにより、画像が別のスレッドに読み込まれるため、アプリの応答性が維持されます。AsyncTaskのドキュメントには、イメージをダウンロードするための簡単な例があり、このヘルパーページに詳細があります。

たとえば、コードを次のように変更する可能性があります(テストを実行せずにこれを記述しているため、いくつかのバグがある可能性があります)。

リストエントリを次のように変更します。

public class CustomList {

    public String iconUrl;
    public String title;
    public CustomList(){
        super();
    }

    public CustomList(String icon, String title) {
        super();
        this.icon = icon;
        this.title = title;
    }
}

次に、アイコンのURLのみをリストに渡します。

次に、AsyncTaskを作成します。

public class ImageDownloader extends AsyncTask<String, Integer, Bitmap> {
     public ImageDownloader(ImageView view){
          mView = view;
     }

     protected Bitmap doInBackground(String... url) {
        Bitmap b = null;
        try {
            URL image_url = new URL(url);
            b = BitmapFactory.decodeStream(image_url.openConnection() .getInputStream());
            list_data = new CustomList[]{
                    new CustomList(b,"Android")};
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return b;
     }

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

次に、アダプタの場合、イメージを設定する代わりに、次の手順を実行します。

new ImageDownloader(holder.thumbnail).execute(cl.icon);

それはあなたが始めるのに十分なはずです。このサンプルにはいくつかの問題があることに注意してください。

  1. 潜在的なメモリリークがあります。一般的に言って、私が行ったように、AsyncTask内のビューまたはアクティビティ(または他のそのようなオブジェクト)への参照を保持するべきではありません。
  2. 電話を回転させてリストを変更すると、古いサムネイルが表示される場合があります。
  3. ビューがリサイクルされると、古いサムネイルが表示される場合があります。
于 2012-07-23T16:32:42.793 に答える