1

I have these next two methods, takescreenshots and saveScreenshot:

public static Bitmap takeScreenshot(View oView)
{    
    Bitmap oBitmap = null;

    if(oView!=null) {
        if (oView.getWidth()>0 & oView.getHeight()>0) {
            oBitmap = Bitmap.createBitmap(oView.getWidth(),
                    oView.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(oBitmap);

            try{
                oView.draw(canvas);
            }catch (Exception ex){
                //log or whatever
            }
        }
    }

    return oBitmap;
}

public static File saveScreenshot(Bitmap oBitmap)
{
    String mPath = ApplicationContext.getActivity().getCacheDir().getAbsolutePath() + "/artandwordsshared_img.jpg";
    File imageFile = new File(mPath);

    try{
        boolean operationOK = true;
        if (imageFile.exists()){
            operationOK = imageFile.delete();
        }
        if (operationOK) {
            operationOK = imageFile.createNewFile();
        }
        if (operationOK) {
            FileOutputStream outputStream = new FileOutputStream(imageFile);
            int quality = 75;
            oBitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
            outputStream.flush();
            outputStream.close();
        }
    }catch(java.io.IOException ex){
        ex.printStackTrace();
    }

    return imageFile;
}

I use this "takeScreenshot" method to capture a view (I use it in some parts of my app) and the other one to save screenshot on device, and I'd like to know if I must/should (regarding good practices) call them through an AsyncTask so they run on background, or if it is not necessary at all. I'm currently using AsyncTask for both and all it's working just fine, but not sure if it is really a must, like it is, for example, for network operations.

Thank you in advance.

Edit 1: Adding the AsyncTask "TakeScreenshot" class.

class TakeScreenshot extends AsyncTask<String, Void, ImageProcessingResult>
{
    private WeakReference<View> view2Capture;
    private ImageListeners listener;
    private String asyncTaskCaller;

    TakeScreenshot(View view2Capture, ImageListeners listener, String asyncTaskCaller)
    {
        this.listener = listener;
        this.view2Capture = new WeakReference<>(view2Capture);
        this.asyncTaskCaller = asyncTaskCaller;
    }

    protected ImageProcessingResult doInBackground(String... urls)
    {
        Bitmap bitmap = null;
        String result = Enum.Result.KO;
        if(view2Capture.get()!=null)
        {
            bitmap = ImageHelper.takeScreenshot(view2Capture.get());
            result = ImageHelper.saveBitmap(bitmap);
        }

        return new ImageProcessingResult(bitmap, result);
    }

    protected void onPostExecute(ImageProcessingResult ipr)
    {
        listener.onScreenCaptureFinished(ipr, asyncTaskCaller);
    }
}

BTW, as for now takeScreenshot method called from AsyncTask is working just fine. Just trying to use good practices, and that's why my post.

Diego Perez
  • 2,188
  • 2
  • 30
  • 58
  • AsyncTask will be deprecated soon. Maybe you should checkout this post over here: https://stackoverflow.com/questions/58767733/android-asynctask-api-deprecating-in-android-11-what-are-the-alternatives – Boe-Dev Nov 15 '19 at 21:52

1 Answers1

0
  1. I'm not sure you will be able to call first function takeScreenshot in the background Thread. Because you are performing operation with UI Draw. In any case, it makes no sense to put this small implementation to the background.

  2. Next function saveScreenshot must be defined in the background Thread for sure. You need to eliminate the jank on UI which you would have because of using in in the foreground. Maybe you will not feel difference on new devices, but in some condition/platforms you will.

UPDATE

Seems like you new to the Android. Of course you can use AsyncTask, but people prefer other tools. AsyncTask is very old and nowadays there are bunch of alternatives. Just try to search for it.

On another hand. AsyncTask based on Java Executors(which includes ThreadPool, "Handler", MessageQueue, etc). For simple actions like yours, you can use just Thread. Clean and simple.

//Just make it once 
private final Handler ui = new Handler(
        Looper.getMainLooper());

//Whenever you need just call next call 
new Thread("Tag").start(() -> {
       //Background Work

      //Whenever you need to submit something to UI
      ui.post(() -> {
          // Foreground Work
      });
   }

})

GensaGames
  • 5,538
  • 4
  • 24
  • 53
  • Thank you very much @GensaGames. I can confirm that taking screenshot in background is working fine, but now that you suggested me to move it to ui thread I'll eliminate AsyncTask, as I'm trying to use best practices for all. I'll only leave async task for the save operation, as you also suggested. – Diego Perez Nov 15 '19 at 21:38
  • Before marking your answer as correct @GensaGames, please see my edit. I've added the AsyncTask class used to call takeScreenshot method, and let's see if you still think the same. – Diego Perez Nov 15 '19 at 21:53
  • @DiegoPerez Updated. – GensaGames Nov 16 '19 at 04:50
  • Thanks again @GensaGames. I'm not new to Android, but of course the language and possibilities are really wide and I don't cover everything, and I also have to say that I'm a .Net developer. Said that, I like your response and appreciate your time and information. I'l start eliminating AsyncTasks little by little, in the end, there are not so many in my app so far. – Diego Perez Nov 16 '19 at 12:29