Skip to content

Instantly share code, notes, and snippets.

@esperia
Last active August 29, 2015 14:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save esperia/11324744 to your computer and use it in GitHub Desktop.
Save esperia/11324744 to your computer and use it in GitHub Desktop.
Require: [Android Asynchronous Http Client](http://loopj.com/android-async-http/). introduced:[Android Asynchronous Http Clientで大きな画像をダウンロードする方法 - Spica*](http://esperia.hatenablog.com/entry/2014/04/27/020516)
public abstract class AsyncGenericHttpResponseHandler<T> extends AsyncHttpResponseHandler {
private static final String LOG_TAG = AsyncGenericHttpResponseHandler.class.getSimpleName();
@SuppressWarnings("unchecked")
@Override
protected void handleMessage(Message msg) {
Object[] response;
if (msg.what == AsyncHttpResponseHandler.SUCCESS_MESSAGE) {
response = (Object[]) msg.obj;
if (response != null && response.length >= 3) {
onSuccess((Integer) response[0], (Header[]) response[1], (T) response[2]);
} else {
Log.e(LOG_TAG, "SUCCESS_MESSAGE didn't got enough params");
}
} else if (msg.what == AsyncHttpResponseHandler.FAILURE_MESSAGE) {
response = (Object[]) msg.obj;
if (response != null && response.length >= 4) {
onFailure((Integer) response[0], (Header[]) response[1], (T) response[2],
(Throwable) response[3]);
} else {
Log.e(LOG_TAG, "FAILURE_MESSAGE didn't got enough params");
}
} else {
super.handleMessage(msg);
}
}
public void onSuccess(Integer integer, Header[] headers, String response) {
}
public void onSuccess(Integer integer, Header[] headers, T response) {
}
public void onFailure(Integer integer, Header[] headers, T response, Throwable e) {
}
/**
* ネットワーク通信後、バックグラウンドで実行されるメソッド。 パース後、 {@link #handleMessage(Message)}
* が実行される
*/
@Override
public void sendResponseMessage(HttpResponse response) throws IOException {
if (!Thread.currentThread().isInterrupted()) {
StatusLine status = response.getStatusLine();
T responseBody = parseResponseInBackground(response.getEntity());
// additional cancellation check as getResponseData() can take
// non-zero time to process
if (!Thread.currentThread().isInterrupted()) {
if (status.getStatusCode() >= 300) {
sendFailureMessage(status.getStatusCode(), response.getAllHeaders(),
responseBody, new HttpResponseException(status.getStatusCode(),
status.getReasonPhrase()));
} else {
sendSuccessMessage(status.getStatusCode(), response.getAllHeaders(),
responseBody);
}
}
}
}
public abstract T parseResponseInBackground(HttpEntity httpEntity) throws IOException;
private void sendSuccessMessage(int statusCode, Header[] headers, T responseBytes) {
sendMessage(obtainMessage(SUCCESS_MESSAGE, new Object[] {
statusCode, headers, responseBytes
}));
}
private void sendFailureMessage(int statusCode, Header[] headers, T responseBody,
Throwable throwable) {
sendMessage(obtainMessage(FAILURE_MESSAGE, new Object[] {
statusCode, headers, responseBody, throwable
}));
}
}
public class AsyncImageHttpResponseHandler extends AsyncGenericHttpResponseHandler<Bitmap> {
private static final String LOG_TAG = AsyncImageHttpResponseHandler.class.getSimpleName();
private File mImageFile;
public AsyncImageHttpResponseHandler(Context context) {
File myCacheDir = context.getDir("imgCache", Context.MODE_PRIVATE);
if (!myCacheDir.exists()) {
myCacheDir.mkdirs();
}
mImageFile = new File(myCacheDir, UUID.randomUUID().toString());
}
@Override
public Bitmap parseResponseInBackground(HttpEntity httpEntity) throws IOException {
InputStream is = httpEntity.getContent();
createFileWithInputStream(is, mImageFile);
Bitmap image = getResampledImage(mImageFile);
return image;
}
/**
* InputStreamオブジェクトにあるデータをファイルに出力 - Java入門
* http://www.syboos.jp/java/doc/write-inputstream-to-file.html
*/
static void createFileWithInputStream(InputStream inputStream, File destFile)
throws IOException {
byte[] buffer = new byte[1024];
int length = 0;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(destFile);
long count = 0;
while ((length = inputStream.read(buffer)) >= 0) {
Log.v(LOG_TAG, "reading...: " + (((float) length * (float) count) / (1024F * 1024F))
+ "[MB]");
fos.write(buffer, 0, length);
count++;
}
fos.close();
fos = null;
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
}
}
}
}
/**
* Android Bitmapをあらかじめ縮小してから読み込む(OutOfMemory対策) - Qiita
* http://qiita.com/exilias/items/38075e08ca45d223cf92
*/
public static Bitmap getResampledImage(File file) throws IOException {
FileInputStream inputStream = new FileInputStream(file);
// 画像サイズ情報を取得する
BitmapFactory.Options imageOptions = new BitmapFactory.Options();
imageOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(inputStream, null, imageOptions);
Log.v("image", "Original Image Size: " + imageOptions.outWidth + " x "
+ imageOptions.outHeight);
inputStream.close();
// もし、画像が大きかったら縮小して読み込む
// 今回はimageSizeMaxの大きさに合わせる
Bitmap bitmap;
int imageSizeMax = 500;
inputStream = new FileInputStream(file);
float imageScaleWidth = (float) imageOptions.outWidth / imageSizeMax;
float imageScaleHeight = (float) imageOptions.outHeight / imageSizeMax;
// もしも、縮小できるサイズならば、縮小して読み込む
if (imageScaleWidth > 2 && imageScaleHeight > 2) {
BitmapFactory.Options imageOptions2 = new BitmapFactory.Options();
// 縦横、小さい方に縮小するスケールを合わせる
int imageScale = (int) Math
.floor((imageScaleWidth > imageScaleHeight ? imageScaleHeight : imageScaleWidth));
// inSampleSizeには2のべき上が入るべきなので、imageScaleに最も近く、かつそれ以下の2のべき上の数を探す
for (int i = 2; i < imageScale; i *= 2) {
imageOptions2.inSampleSize = i;
}
bitmap = BitmapFactory.decodeStream(inputStream, null, imageOptions2);
Log.v("image", "Sample Size: 1/" + imageOptions2.inSampleSize);
} else {
bitmap = BitmapFactory.decodeStream(inputStream);
}
inputStream.close();
return bitmap;
}
}
@esperia
Copy link
Author

esperia commented Apr 26, 2014

Request:

public class DownloadLargeImageActivity extends FragmentActivity {

    private static AsyncHttpClient sClient = new AsyncHttpClient();

    private ImageView mImageView;

    ...

    private void request() {
        sClient.setTimeout(Integer.MAX_VALUE);
        sClient.get("http://example.com/images/extra_large_photo.jpg",
                new AsyncImageHttpResponseHandler(this) {
                    @Override
                    public void onSuccess(Integer integer, Header[] headers, Bitmap response) {
                        mImageView.setImageBitmap(response);
                    }

                    @Override
                    public void onFailure(Integer integer, Header[] headers, Bitmap response,
                            Throwable e) {
                    }

                    @Override
                    public void onFinish() {
                    }
                });
    }

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment