1

I know that it's possible to call the method getDialog.dismiss if I use AsyncTask as an inner class but due to the amount of code in the class I decided to have another class for AsyncTask now if I try calling the method it says that Non-static method 'getDialog()' cannot be referenced from a static context. How can I make it work?

public class BackgroundImageResize extends AsyncTask<Uri, Integer, byte[]> 
      {

Bitmap mBitmap;
byte[] mUploadBytes;
Context context;

public BackgroundImageResize(Context ctx) {
    context = ctx.getApplicationContext();
}

public BackgroundImageResize(Bitmap bitmap) {
    if (bitmap != null) {
        this.mBitmap = bitmap;
    }
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
    Toast.makeText(context, "compressing image", 
Toast.LENGTH_SHORT).show();
    progressBar.setVisibility(View.VISIBLE);
}

@Override
protected byte[] doInBackground(Uri... params) {

    try {
        mBitmap = 
MediaStore.Images.Media.getBitmap(context.getContentResolver(), 
params[0]);
    } catch (IOException e) {
        e.printStackTrace();
    }

    byte[] bytes;
    bytes = getBytesFromBitmap(mBitmap, 70);
    return bytes;
}

@Override
protected void onPostExecute(byte[] bytes) {
    super.onPostExecute(bytes);
    mUploadBytes = bytes;
    progressBar.setVisibility(View.INVISIBLE);
    //execute the upload task

    ChooseImageActivity.mOnInputListener.sendInput(mUploadBytes);
    ChooseImageActivity.getDialog().dismiss();


}

public static byte[] getBytesFromBitmap(Bitmap bitmap, int quality) {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, quality, stream);
    return stream.toByteArray();
}
}

3 Answers3

2

Pass on a callback on the constructor of the AsyncTask and invoke it onPostExecute.

See this

Arka Prava Basu
  • 2,366
  • 3
  • 18
  • 34
2

I suggest creating an interface:

interface MyInterface{
void onTaskFinished(byte[] bytes)
}

Init and use this interface inside your BackgroundImageResize class:

myInterface.onTaskFinished(mUploadBytes)

Make a setter for it so you can receive the callback in your Activity. Implement this interface inside of your MainActivity and don't forget to use the setter previously created after you init BackgroundImageResize class.

Your Activity should now overwrite onTaskFinished(byte[] bytes) and when task is finished you can use:

getDialog().dismiss();

Hope that helps.

Alex
  • 962
  • 4
  • 15
  • Hi, Alex after writing all these I dont have an error but the dialog is still there. –  Jul 18 '19 at 12:35
  • Hi Ronnie, couple of things to try: Log onTaskFinished(byte[] bytes) and see if the callback is working. If it's working use the reference of the created dialog to dismiss it. – Alex Jul 18 '19 at 12:57
1

Pass reference to your activity or the class which has access to your dialog in the constructor of your AsyncTask class. And use a weak reference to your activity and access fields like progressBar from that weak reference. Like this:

public class MainActivity extends AppCompatActivity {

    private ProgressBar progressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        progressBar = (ProgressBar) findViewById(R.id.progress_bar);
    }



    static class BackgroundImageResize extends AsyncTask<Uri, Integer, byte[]> {

        WeakReference<MainActivity> mActivity;

        Bitmap mBitmap;
        byte[] mUploadBytes;

        public BackgroundImageResize(Bitmap bitmap, MainActivity activity) {

            mActivity = new WeakReference<MainActivity>(activity);

            if (bitmap != null) {
                this.mBitmap = bitmap;
            }
       }


        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Toast.makeText(mActivity.get(), "compressing image",
                    Toast.LENGTH_SHORT).show();
            mActivity.get().progressBar.setVisibility(View.VISIBLE);
        }

        @Override
        protected byte[] doInBackground(Uri... params) {

            try {
                 mBitmap = MediaStore.Images.Media.getBitmap(mActivity.get().getContentResolver(),
                            params[0]);
            } catch (IOException e) {
                e.printStackTrace();
            }

            byte[] bytes;
            bytes = getBytesFromBitmap(mBitmap, 70);
            return bytes;
        }

        @Override
        protected void onPostExecute(byte[] bytes) {
            super.onPostExecute(bytes);
            mUploadBytes = bytes;
            mActivity.get().progressBar.setVisibility(View.INVISIBLE);
            //execute the upload task


        }

        public byte[] getBytesFromBitmap(Bitmap bitmap, int quality) {
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, stream);
            return stream.toByteArray();
        }
    }
}
Sina
  • 2,683
  • 1
  • 13
  • 25
  • mActivity.get() returns a weak reference of the MainActivity. To know more about weak reference and memory leaks in android read this: https://developer.android.com/reference/java/lang/ref/WeakReference – Sina Jul 18 '19 at 12:26
  • Hi, Sina No I don't have nested class also the method you wrote return null pointer exception. –  Jul 18 '19 at 12:33
  • Hi. I've just updated the answer. If you need context you can call mActivity.get() which returns the weak reference activity. – Sina Jul 18 '19 at 13:11