AsyncTask all i get is a blank/black texture screen

If we assume your AsyncTask actually works, then I don't understand how this line of code would save you any time: Bitmap bitmap=new BitmapWorkerTask().execute(myuri).get();. It is called from the loadTextures() method which appears to be run the the UI thread. The .get() method would force the UI thread to wait until the task is complete, so there would be no reason to run it in an AsyncTask.

Assuming that you have been modifying your code and the code you posted isn't the version that actually saves you time, and assuming that the AsyncTask works, then I think the issue is making sure the results of the BitmapWorkerTask are pushed into the UI thread when they are done. You would do this by using the AsyncTask's onPostExecute() method, which is run on the UI thread and has access to the results of the doInBackground() method. So here is an example, where I modify the loadTexture() method to take the result Bitmap in as a parameter, and use the onPostExecute() method to make sure that the loadTexture() method is called only after the Bitmap is loaded...
view plaincopy to clipboardprint?
Note: Text content in the code blocks is automatically word-wrapped
    /* load the texture bitmap properly */ 
    private void loadTextures(Bitmap bitmap) {  
        // Generate textures  
        GLES20.glGenTextures(2, mTextures, 0);  
        mEffectContext = EffectContext.createWithCurrentGlContext();  
        mTexRenderer.init();  
 
        // Load input bitmap  
        try {  
            //load Bitmap from previous activity  
            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();  
        }  
    }  
 
    class BitmapWorkerTask extends AsyncTask<Uri, Void, Bitmap> {  
        Uri uri;  
 
        @Override 
        protected Bitmap doInBackground(Uri... imageuri) {  
            uri = imageuri[0];  
            return decodeSampledBitmapFromResource(uri, dw, dh);  
        }  
          
        @Override /* When loading bitmap is done, make sure it is displayed. */ 
        protected void onPostExecute(Bitmap bitmap) {  
            // have bitmap, so load it to GL context  
            loadTexttures(bitmaps[0]);  
            // next time onDraw is called, it should do the rendering  
            mInitialized = true;  
              
            // do the rendering now  
            processEffectsAndRender();  
        }  
    } 
    /* load the texture bitmap properly */
    private void loadTextures(Bitmap bitmap) {
        // Generate textures
        GLES20.glGenTextures(2, mTextures, 0);
        mEffectContext = EffectContext.createWithCurrentGlContext();
        mTexRenderer.init();

        // Load input bitmap
        try {
            //load Bitmap from previous activity
            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();
        }
    }

    class BitmapWorkerTask extends AsyncTask<Uri, Void, Bitmap> {
        Uri uri;

        @Override
        protected Bitmap doInBackground(Uri... imageuri) {
            uri = imageuri[0];
            return decodeSampledBitmapFromResource(uri, dw, dh);
        }
       
        @Override /* When loading bitmap is done, make sure it is displayed. */
        protected void onPostExecute(Bitmap bitmap) {
            // have bitmap, so load it to GL context
            loadTexttures(bitmaps[0]);
            // next time onDraw is called, it should do the rendering
            mInitialized = true;
           
            // do the rendering now
            processEffectsAndRender();
        }
    }
So the onPostExecute() method triggers the loadTexture() method, signals that the loading is done, and then makes sure the effects are rendered. I modified a couple of the other methods to make sure that things happen only when the bitmap is available. First, the onDrawFrame() method is modified to only work after the bitmap is loaded completely (the mInitialized variable is true). I also broke the rest of what was in the onDrawFrame() method out into its own method so it could be called either from onDrawFrame() of from the onPostExecute() methods:
view plaincopy to clipboardprint?
Note: Text content in the code blocks is automatically word-wrapped
    /* draw frame if bitmap and effects are ready... */ 
    public void onDrawFrame(GL10 gl) {  
        if (mInitialized) {  
            processEffectsAndRender();  
        }  
    }  
      
    /* initialize effect and draw */ 
    private void processEffectsAndRender() {  
        if (mCurrentEffect != R.id.none) {  
            // if an effect is chosen initialize it and apply it to the texture  
            initEffect();  
            //applyEffect();  
        }  
        renderResult();  
    } 
    /* draw frame if bitmap and effects are ready... */
    public void onDrawFrame(GL10 gl) {
        if (mInitialized) {
            processEffectsAndRender();
        }
    }
   
    /* initialize effect and draw */
    private void processEffectsAndRender() {
        if (mCurrentEffect != R.id.none) {
            // if an effect is chosen initialize it and apply it to the texture
            initEffect();
            //applyEffect();
        }
        renderResult();
    }
Finally, I wanted to kick the BitmapWorkerTask off as soon as possible, so I figured I would run it from the onCreate() method:
view plaincopy to clipboardprint?
Note: Text content in the code blocks is automatically word-wrapped
    @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;  
 
        /* start loading Bitmap as soon as possible. */ 
        mInitialized = false;  
        myuri = Uri.parse(getIntent().getStringExtra("uri"));  
        new BitmapWorkerTask().execute(myuri);  
          
    } 
    @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;

        /* start loading Bitmap as soon as possible. */
        mInitialized = false;
        myuri = Uri.parse(getIntent().getStringExtra("uri"));
        new BitmapWorkerTask().execute(myuri);
       
    }

So in this situation, the onCreate() method starts loading the BitmapWorkerTask. When the BitmapWorkerTask is done, it makes sure the bitmap is sized and processed, and rendered. Meamwhile, if the onDrawFrame() is called before the bitmap is complete, it won't do anything, afterwards, it will display the results. all this is relatively naive, of course. I haven't used OpenGL on the Android yet and I didn't compile or test the code. all I did was to organize it in a way that made sure the code that needed to execute only after the Bitmap was loaded did so, and to make sure that that code gets called as soon as the Bitmap is loaded.

This will NOT make the bitmap load faster. If it takes 7 seconds to load the bitmap that is how long it takes, and it still shouldn't show up until the end of that load time. What this will do is allow your UI remain responsive and allow other things to happen WHILE the bitmap loads.

Back  [1] [2] [3] Next

Copyright © 2007-2012 www.chuibin.com Chuibin Copyright