位图内存泄漏大图像

时间:2016-05-23 14:23:47

标签: android bitmap

是否有任何库或任何有效的方法来处理位图。

我需要向服务器发送1-10张图像。图像为3至15兆字节。 我们以base64格式发送字符串。但是这个过程需要太多的内存和应用程序爆炸。我试图优化应用程序和realese内存,但在大多数情况下再次获得内存异常,我也使用大堆。

 protected Void doInBackground(Void... voids) {

            for (int i = 0; i < mUriList.size(); i++) {
                Log.e("encodeImage bitmap", Integer.toString(i) + "  " + mUriList.get(i));
                mBitmap = getBitmapFromUri(mUriList.get(i));
                String imageNamePath = mImageNameList.get(i);

                // FIXME: 5/23/16 OOM kod 10 slika

                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                mBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);

                byte[] array = stream.toByteArray();
                encoded_string = Base64.encodeToString(array, Base64.DEFAULT);

                array = null;
                //encoded_image_list.add(encoded_string);
                makeRequest(encoded_string, imageNamePath, i);
                mBitmap.recycle();
                mBitmap = null;
                try {
                    stream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                stream = null;
                encoded_string = null;
                System.gc();
            }
            return null;
        }....

从位图获取图像

public Bitmap getBitmapFromUri(Uri uri) {
        Bitmap bitmap = null;
        try {
            bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bitmap;
    }

ps:我无法降低图像质量!

1 个答案:

答案 0 :(得分:0)

因此,假设您有能力在服务器端重写请求,以通过Multipart POST请求处理图像上传。 (因为你也写了后端API,确认了!)

我在这里用OkHttp客户端获取了一段示例代码:

public final class PostMultipart {
  /**
   * The imgur client ID for OkHttp recipes. If you're using imgur for anything other than running
   * these examples, please request your own client ID! https://api.imgur.com/oauth2
   */
  private static final String IMGUR_CLIENT_ID = "9199fdef135c122";
  private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");

  private final OkHttpClient client = new OkHttpClient();

  public void run() throws Exception {
    // Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image
    RequestBody requestBody = new MultipartBody.Builder()
        .setType(MultipartBody.FORM)
        .addFormDataPart("title", "Square Logo")
        .addFormDataPart("image", "logo-square.png",
            RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))
        .build();

    Request request = new Request.Builder()
        .header("Authorization", "Client-ID " + IMGUR_CLIENT_ID)
        .url("https://api.imgur.com/3/image")
        .post(requestBody)
        .build();

    try (Response response = client.newCall(request).execute()) {
      if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

      System.out.println(response.body().string());
    }
  }

  public static void main(String... args) throws Exception {
    new PostMultipart().run();
  }
}

Github OkHttp Recipes上的完整示例:https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/PostMultipart.java

AFAIK,OkHttp客户端会将图像文件读取并上传为较小的流。这样可以避免在读取base64字符串时必须将图像作为大块内存处理的情况。