2012-01-06 7 views
2

サーバーから50-70Kのサイズの写真を約20枚読み込み、ListViewに表示しています。当初はデータをBitmapとして保存していたため、メモリが不足していました。その後、これらのビットマップファイルをすべて圧縮し、コンテンツプロバイダMediaに保存することに決めました。したがって、私のアダプターでは、ユーザーデータには画像ファイルへのUriしか含まれていません。ImageViewでAndroidメモリの割り当てはどのように機能しますか?

しかし、問題はまったく修正されませんでした。少し長く実行されましたが、約10枚ほどの画像をロードした後もクラッシュしました。ここにコンパイラからのエラーログがあります。
1048576-byte external allocation too large for this process
VM won't let us allocate 1048576 bytes

私も私のImageViewにそれを設定した後、各bitmapデータをクリーンアップ、プラス私のsdcard

@Override 
    public void onDestroy() { 
     // clean up 
     for (User user : userList) { 
      getContentResolver().delete(user.getImageUri(), null, null); 
     } 
     super.onDestroy(); 
    } 


    private Uri constructUriFromBitmap(Bitmap bitmap) { 
     ContentValues values = new ContentValues(1); 
     values.put(Media.MIME_TYPE, "image/jpeg"); 
     Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values); 
     try { 
      OutputStream outStream = getContentResolver().openOutputStream(uri); 
      bitmap.compress(Bitmap.CompressFormat.JPEG, 50, outStream); 
      outStream.close(); 
     } 
     catch (Exception e) { 
      Log.e(TAG, "exception while writing image", e); 
     } 
     bitmap.recycle(); 
     return uri; 
    } 

に格納されているすべての画像ファイルは、今私はアイデアを使い果たし削除私は本当にこの場合に何がうまくいかないのか分かりません。誰かがこの問題を経験したことが私にいくつかの光を当てることができるのだろうか?

コードはかなり長いので、私は唯一の主な機能を抽出します。

public class FriendFeed { 
    // required parameters 
    private final int activityId; // in case we want to handle the detail of 
            // this activity 
    private final int friendId; 
    private final String friendName; 
    private final Challenge.Type challengeType; 
    private final String activityTime; 
    private final String placeName; 

    // optional parameter 
    private String challengeName; 
    private String challengeDescription; 
    private Uri activitySnapPictureUri = null; 
    private Uri friendPictureUri = null; 
    private String activityComment; 

そして、ここでは私の主な機能です::

@Override 
protected Boolean doInBackground(Void...voids) { 
      JSONArray array = JsonHelper.getJsonArrayFromUrlWithData(GET_FRIEND_FEED_URL, datas); 
      if (array != null) { 
       try { 
        for (int i = 0; i < array.length(); ++i) { 
         Uri snapPictureUri = null; 
         Uri userPictureUri = null; 

         if (Challenge.returnType(array.getJSONObject(i).getString("challenges_tbl_type")) == Challenge.Type.SNAP_PICTURE) { 
          snapPictureUri = constructUriFromBitmap(ImageHelper.downloadImage(array.getJSONObject(i).getString("activity_tbl_snap_picture_url"))); 
         } 

         if(ImageHelper.downloadImage(array.getJSONObject(i).getString("users_tbl_user_image_url")) != null) { 
          userPictureUri = constructUriFromBitmap(ImageHelper.downloadImage(array.getJSONObject(i).getString("users_tbl_user_image_url"))); 
         } 

         publishProgress(
          new FriendFeed.Builder(
            // required parameters 
            array.getJSONObject(i).getInt("activity_tbl_id"), 
            array.getJSONObject(i).getInt("friends_tbl_friend_id"), 
            array.getJSONObject(i).getString("users_tbl_username"), 
            Challenge.returnType(array.getJSONObject(i).getString("challenges_tbl_type")), 
            array.getJSONObject(i).getString("activity_tbl_created"), 
            array.getJSONObject(i).getString("spots_tbl_name")) 
             // optional parameters 
             .challengeName(array.getJSONObject(i).getString("challenges_tbl_name")) 
             .challengeDescription(array.getJSONObject(i).getString("challenges_tbl_description")) 
             .activitySnapPictureUri(snapPictureUri) 
             .friendPictureUri(userPictureUri) 
             .activityComment(array.getJSONObject(i).getString("activity_tbl_comment")) 
              .build()); 
        } 
       } 
       catch (JSONException e) { 
        Log.e(TAG + "GetFriendFeedTask.doInBackGround(Void ...voids) : ", "JSON error parsing data" + e.toString()); 
       } 
       return true; 
      } 
      else { 
       return false; 
      } 
     } 

答えて

1

Androidがあたりを強制 ここでは私のUser classデータであり、プロセスのメモリ割り当ての制限が24MBになります。それ以上は割り当てることができません。しかし、70Kそれぞれの20枚の写真が唯一の1.4メガバイトに達する必要があります...ので、私の推測:

  1. あなたのために利用できる1.4メガバイト未満がありますように、たぶん、あなたは、あなたのアプリケーションの他の部分でビットマップを割り当てていますこのListViewのビットマップどこか

  2. メモリリークあなたは本当にあなたが使用しているすべてのビットマップが必要と判断した場合、あなたはビットマップがこの大であるか、これだけの解像度を持っている必要があります確信していますか?それらを減らすことが役に立ちます。

他のすべてが失敗し、メモリにたくさんのビットマップが必要な場合は、いつでもOpenGLテクスチャを使用できます。

+0

迅速な対応をありがとうございます。私の他の活動のほとんどはまだ 'ビットマップ'を読み込んでいます。上記の方法で実際にうまくいくと後でそれらを変更します。しかし、たとえ私が他人を変えなかったとしても、私はこの活動だけを実行し、他の活動はどのようにかかわったのですか? – Chan

+0

@BrunoOliveiraたぶんあなたはアクティビティAの画像を持っていて、アクティビティBに移動してそこに画像があります。アクティビティAは破壊されず、アクティビティBのバックグラウンドで実行されています。 –

関連する問題