package me.xiaopan.sketchsample.fragment;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import me.xiaopan.androidinjector.InjectContentView;
import me.xiaopan.androidinjector.InjectView;
import me.xiaopan.sketch.Configuration;
import me.xiaopan.sketch.Sketch;
import me.xiaopan.sketch.SketchMonitor;
import me.xiaopan.sketch.cache.BitmapPoolUtils;
import me.xiaopan.sketch.request.UriScheme;
import me.xiaopan.sketch.util.SketchUtils;
import me.xiaopan.sketchsample.AssetImage;
import me.xiaopan.sketchsample.MyFragment;
import me.xiaopan.sketchsample.R;
@InjectContentView(R.layout.fragment_in_bitmap_test)
public class InBitmapTestFragment extends MyFragment {
@InjectView(R.id.image_inBitmapTestFragment)
ImageView imageView;
@InjectView(R.id.text_inBitmapTestFragment)
TextView textView;
@InjectView(R.id.button_inBitmapTestFragment_sizeSame)
Button sizeSameButton;
@InjectView(R.id.button_inBitmapTestFragment_largeSize)
Button largeSizeButton;
@InjectView(R.id.button_inBitmapTestFragment_sizeNoSame)
Button sizeNoSameButton;
@InjectView(R.id.button_inBitmapTestFragment_inSampleSize)
Button inSampleSizeButton;
@InjectView(R.id.view_inBitmapTestFragment_pageNumber)
TextView pageNumberTextView;
@InjectView(R.id.view_inBitmapTestFragment_last)
View lastView;
@InjectView(R.id.view_inBitmapTestFragment_next)
View nextView;
int index = 0;
Configuration configuration;
private View currentMode;
private static Bitmap decodeImage(Context context, String imageUri, BitmapFactory.Options options) {
UriScheme uriScheme = UriScheme.valueOfUri(imageUri);
if (uriScheme == null) {
return null;
}
InputStream inputStream;
if (uriScheme == UriScheme.FILE) {
try {
inputStream = new FileInputStream(imageUri);
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
} else if (uriScheme == UriScheme.ASSET) {
try {
inputStream = context.getAssets().open(UriScheme.ASSET.crop(imageUri));
} catch (IOException e) {
e.printStackTrace();
return null;
}
} else if (uriScheme == UriScheme.DRAWABLE) {
try {
inputStream = context.getResources().openRawResource(Integer.valueOf(UriScheme.DRAWABLE.crop(imageUri)));
} catch (Resources.NotFoundException e) {
e.printStackTrace();
return null;
}
} else {
return null;
}
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeStream(inputStream, null, options);
} finally {
SketchUtils.close(inputStream);
}
return bitmap;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
configuration = Sketch.with(getActivity()).getConfiguration();
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
lastView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
--index;
if (index < 0) {
index = AssetImage.IN_BITMAP_SAMPLES.length - Math.abs(index);
}
currentMode.performClick();
}
});
nextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
index = ++index % AssetImage.IN_BITMAP_SAMPLES.length;
currentMode.performClick();
}
});
sizeSameButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
testSizeSame();
updateCheckedStatus(v);
}
});
largeSizeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
testLargeSize();
updateCheckedStatus(v);
}
});
sizeNoSameButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
testSizeNoSame();
updateCheckedStatus(v);
}
});
inSampleSizeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
inSampleSize();
updateCheckedStatus(v);
}
});
sizeSameButton.performClick();
}
private void updateCheckedStatus(View newView) {
if (currentMode != null) {
currentMode.setEnabled(true);
}
newView.setEnabled(false);
currentMode = newView;
pageNumberTextView.setText(String.format("%d/%d", index + 1, AssetImage.IN_BITMAP_SAMPLES.length));
}
private void testSizeSame() {
new TestTask(getActivity()) {
@Override
protected void configOptions(BitmapFactory.Options options) {
if (BitmapPoolUtils.sdkSupportInBitmap()) {
options.inBitmap = Bitmap.createBitmap(options.outWidth, options.outHeight, options.inPreferredConfig);
options.inMutable = true;
}
super.configOptions(options);
}
}.execute(AssetImage.IN_BITMAP_SAMPLES[index % AssetImage.IN_BITMAP_SAMPLES.length]);
}
private void testLargeSize() {
new TestTask(getActivity()) {
@Override
protected void configOptions(BitmapFactory.Options options) {
if (BitmapPoolUtils.sdkSupportInBitmap()) {
options.inBitmap = Bitmap.createBitmap(options.outWidth + 10, options.outHeight + 5, options.inPreferredConfig);
options.inMutable = true;
}
super.configOptions(options);
}
}.execute(AssetImage.IN_BITMAP_SAMPLES[index % AssetImage.IN_BITMAP_SAMPLES.length]);
}
private void testSizeNoSame() {
new TestTask(getActivity()) {
@Override
protected void configOptions(BitmapFactory.Options options) {
if (BitmapPoolUtils.sdkSupportInBitmap()) {
options.inBitmap = Bitmap.createBitmap(options.outHeight, options.outWidth, options.inPreferredConfig);
options.inMutable = true;
}
super.configOptions(options);
}
}.execute(AssetImage.IN_BITMAP_SAMPLES[index % AssetImage.IN_BITMAP_SAMPLES.length]);
}
private void inSampleSize() {
new TestTask(getActivity()) {
@Override
protected void configOptions(BitmapFactory.Options options) {
if (BitmapPoolUtils.sdkSupportInBitmap()) {
options.inSampleSize = 2;
int finalWidth = SketchUtils.ceil(options.outWidth, options.inSampleSize);
int finalHeight = SketchUtils.ceil(options.outHeight, options.inSampleSize);
options.inBitmap = Bitmap.createBitmap(finalWidth, finalHeight, options.inPreferredConfig);
options.inMutable = true;
}
super.configOptions(options);
}
}.execute(AssetImage.IN_BITMAP_SAMPLES[index % AssetImage.IN_BITMAP_SAMPLES.length]);
}
private class TestTask extends AsyncTask<String, Integer, Bitmap> {
protected StringBuilder builder = new StringBuilder();
private Context context;
public TestTask(Context context) {
this.context = context.getApplicationContext();
}
@Override
protected Bitmap doInBackground(String... params) {
String imageUri = params[0];
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
decodeImage(context, imageUri, options);
if (options.outWidth <= 1 || options.outHeight <= 1) {
return null;
}
options.inSampleSize = 1; // 这很重要4.4以下必须得是1
configOptions(options);
builder.append("imageUri: ").append(imageUri);
int sizeInBytes = SketchUtils.computeByteCount(options.outWidth, options.outHeight, options.inPreferredConfig);
builder.append("\n").append("image: ")
.append(options.outWidth).append("x").append(options.outHeight)
.append(", ").append(options.inPreferredConfig)
.append(", ").append(sizeInBytes);
builder.append("\n").append("inSampleSize: ").append(options.inSampleSize);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
if (options.inBitmap != null) {
builder.append("\n")
.append("inBitmap: ")
.append(Integer.toHexString(options.inBitmap.hashCode()))
.append(", ").append(options.inBitmap.getWidth()).append("x").append(options.inBitmap.getHeight())
.append(", ").append(options.inBitmap.isMutable())
.append(", ").append(SketchUtils.getByteCount(options.inBitmap));
} else {
builder.append("\n").append("inBitmap: ").append("null");
}
}
Bitmap newBitmap = null;
try {
options.inJustDecodeBounds = false;
newBitmap = decodeImage(context, imageUri, options);
} catch (OutOfMemoryError e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
SketchMonitor monitor = Sketch.with(getActivity()).getConfiguration().getMonitor();
BitmapPoolUtils.inBitmapThrow(e, options, monitor, configuration.getBitmapPool(), imageUri, 0, 0);
}
if (newBitmap != null) {
builder.append("\n").append("newBitmap: ")
.append(Integer.toHexString(newBitmap.hashCode()))
.append(", ").append(newBitmap.getWidth()).append("x").append(newBitmap.getHeight())
.append(", ").append(newBitmap.isMutable())
.append(", ").append(SketchUtils.getByteCount(newBitmap));
} else {
builder.append("\n").append("newBitmap: ").append("null");
}
return newBitmap;
}
protected void configOptions(BitmapFactory.Options options) {
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
Bitmap oldBitmap = null;
BitmapDrawable oldDrawable = (BitmapDrawable) imageView.getDrawable();
if (oldDrawable != null) {
oldBitmap = oldDrawable.getBitmap();
}
imageView.setImageBitmap(bitmap);
textView.setText(builder.toString());
if (!BitmapPoolUtils.freeBitmapToPool(oldBitmap, configuration.getBitmapPool())) {
Log.w("BitmapPoolTest", "recycle");
}
}
}
}