我正在使用Open GL ES 2.0对位图执行某些效果,现在如果我直接在UI线程上加载位图需要很多时间,因此我使用AsyncTask ....
问题: -
当我使用AsyncTask时,我得到的是一个空白/黑色纹理屏幕,没有asynctask它会在7-8秒后根据大小显示位图。
我确实检查了许多其他相似的问题,但他们的问题似乎有所不同。
以下是代码: -
public class TinypostFilters extends Activity implements GLSurfaceView.Renderer {
private Uri myuri;
int dw;
int dh;
private GLSurfaceView mEffectView;
private int[] mTextures = new int[2];
private EffectContext mEffectContext;
private Effect mEffect;
private TextureRenderer mTexRenderer = new TextureRenderer();
private int mImageWidth;
private int mImageHeight;
private boolean mInitialized = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tinypost_filters);
/*
* Initialize renderer and set it to only render when explicitly
* requested with the RENDERMODE_WHEN_DIRTY option.
*/
mEffectView = (GLSurfaceView) findViewById(R.id.effectsview);
mEffectView.setEGLContextClientVersion(2);
mEffectView.setRenderer(this);
mEffectView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
mCurrentEffect = R.id.none;
}
@Override
public void onDrawFrame(GL10 gl) {
if (!mInitialized) {
// Only need to do this once
mEffectContext = EffectContext.createWithCurrentGlContext();
mTexRenderer.init();
loadTextures();
mInitialized = true;
}
if (mCurrentEffect != R.id.none) {
// if an effect is chosen initialize it and apply it to the texture
initEffect();
//applyEffect();
}
renderResult();
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if (mTexRenderer != null) {
mTexRenderer.updateViewSize(width, height);
}
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
private void loadTextures() {
// Generate textures
GLES20.glGenTextures(2, mTextures, 0);
// Load input bitmap
try {
//load Bitmap from previous activity
myuri = Uri.parse(getIntent().getStringExtra("uri"));
Bitmap bitmap=new BitmapWorkerTask().execute(myuri).get();
mImageWidth = bitmap.getWidth();
mImageHeight = bitmap.getHeight();
mTexRenderer.updateTextureSize(mImageWidth, mImageHeight);
// Upload to texture
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[0]);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
// Set texture parameters
GLToolbox.initTexParams();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void renderResult() {
if (mCurrentEffect != R.id.none) {
// if no effect is chosen, just render the original bitmap
mTexRenderer.renderTexture(mTextures[1]);
} else {
// render the result of applyEffect()
mTexRenderer.renderTexture(mTextures[0]);
}
}
//this method decodes the bitmap
public Bitmap decodeSampledBitmapFromResource(Uri uri, int reqWidth,
int reqHeight) {
Display currentDisplay = getWindowManager().getDefaultDisplay();
Point size = new Point();
currentDisplay.getSize(size);
dw = size.x;
dh = size.y;
// Load up the image's dimensions not the image itself
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
Bitmap bmp = null;
try {
bmp = BitmapFactory.decodeStream(getContentResolver()
.openInputStream(uri), null, bmpFactoryOptions);
} catch (Exception e) {
}
int widthRatio = (int) Math.ceil(bmpFactoryOptions.outWidth
/ (float) reqWidth);
int heightRatio = (int) Math.ceil(bmpFactoryOptions.outHeight
/ (float) reqHeight);
if (heightRatio > 1 && widthRatio > 1) {
if (heightRatio > widthRatio) {
bmpFactoryOptions.inSampleSize = heightRatio;
} else {
bmpFactoryOptions.inSampleSize = widthRatio;
}
bmpFactoryOptions.inJustDecodeBounds = false;
try {
bmp = BitmapFactory.decodeStream(getContentResolver()
.openInputStream(uri), null, bmpFactoryOptions);
} catch (Exception e) {
}
}
return bmp;
}
class BitmapWorkerTask extends AsyncTask<Uri, Void, Bitmap> {
Uri uri;
@Override
protected Bitmap doInBackground(Uri... imageuri) {
uri = imageuri[0];
return decodeSampledBitmapFromResource(uri, dw, dh);
}
}
}
我已尝试过这里和那里的重构,但没有任何成功......感谢任何帮助,谢谢!
答案 0 :(得分:0)
您的decodeSampledBitmap()
方法中有几个地方可以捕获异常但您不记录它们或打印异常的堆栈跟踪。我会在这些块中执行类似e.printStackTrace()
的操作,只是为了帮助调试并确保不会抛出异常。
此外,最好从UI线程解码位图(您不希望在解码时冒ANR的风险),但我不确定它是否会加快解码和显示所需的时间你的形象。
答案 1 :(得分:0)
在AsyncTask
中,您需要添加onPostExecute(...)
方法来处理从doInBackground()
返回的值。您可以在此SO问题中找到完整AsynTask
实施的示例: