0

I am developing a coloring book. And I want the state of the drawing to be saved when the user exits the application or changes the screen orientation.

My method works correctly when I set it to a button.

But when I add it to onPause it saves only part of the image.

I have already added execution of it in a separate thread, but this does not help either.

Here is my method:

private void setSavedBitmap(Bitmap finalBitmap) {

    file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
            "savedBitmap1.png");

    new Thread(new Runnable() {
        public void run() {
            try {
                FileOutputStream fos = null;
                    fos = new FileOutputStream(file);
                    finalBitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
                    if (fos != null) fos.close();
            } catch (Exception e) {
                e.printStackTrace();
            };
        }
    }).start();

    SharedPreferencesFactory.saveString(this, "savedBitmap1", file.getPath());
}

onPause:

@Override
protected void onPause() {
    super.onPause();
    setSaveColor();
    setSavedBitmap(colourImageView.getmBitmap());
}

on button:

save.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        setSavedBitmap(colourImageView.getmBitmap());
        Toast.makeText(ColoringActivity.this, "You state image was saved",
                Toast.LENGTH_LONG).show();
    }
});

UPD. If I close the application and go to Device File Explorer to open my bitmap file, I see the following message: enter image description here

I don't understand why this method works fine for a button but doesn't work in onPause()

It also turned out that if you change the format from PNG to JPEG, the method works fine even in onPause(). But I only need PNG

ttcreator
  • 31
  • 5
  • You're swallowing exceptions in writing the file. Most likely you're getting one. Check the logs for a stack trace, there's most likely one there. Ignore the people telling you to use Service or WorkManager, you don't use those to save data in onPause. Neither would have access to the data, and by the time WorkManager rolled around your app would likely have to be restarted. They also don't seem to understand the difference between an Activity being paused and exiting the app. – Gabe Sechan Jul 27 '22 at 15:41
  • I've found that the JPEG format works correctly for my application, and the PNG can't be fully preserved when the application is destroyed. But I need PNG. The solutions suggested here didn't work for me. – ttcreator Jul 29 '22 at 06:17
  • Once again- what exception is being thrown. Find it in your logs. Something is going wrong and you're swallowing it and ignoring it. – Gabe Sechan Jul 29 '22 at 16:31
  • @GabeSechan When i close my app i nothing not see in my logs. No Exceptions. Im newbie in developing and may be i not understanding you – ttcreator Jul 30 '22 at 08:07

2 Answers2

-1

Thread will not survive after your app is kill i.e process is killed. So you need to use some kind of background execution framework Like a Service.

But normal Service has background limitations so it will also get killed so it has to be a foreground Service . the other option IntentService is deprecated .

you can use JobIntentService to save the bitmap. but it does not guarantees immediate execution which in your case is mandatory See This thread. On other hand WorkManger works in same way .

So conclusion here is use a Foreground Service to save the Bitmap . This will work well for your Usecase.

ADM
  • 20,406
  • 11
  • 52
  • 83
  • Services don't survive the killing of the process either. So this wouldn't work. – Gabe Sechan Jul 27 '22 at 15:37
  • What about foreground service? It keeps the process going so process is not gonna killed . Isn't that right or I have been sleeping for too long and it's changed now. – ADM Jul 27 '22 at 15:40
  • Wouldn't help. The problem is unlikely to be his process being killed- his activity is being paused, that doesn't mean the process is killed. You have time after process pause to continue processing when going into the background, and writing the file takes milliseconds. More likely he has some sort of file writing exception he's swallowing- notice he's catching exception, not even just ioexception. He probably had a disk writing error or went oom compressing it. – Gabe Sechan Jul 27 '22 at 15:43
  • I know all that . I was only talking about some immediate task which needed to be done . Also taking into account that this task can take any amount of time and need to execute immediately .. that's all . Your theory is also right about question. – ADM Jul 27 '22 at 15:47
-1

It is always recommended to do this type of operation in the background thread. You can achieve this in multiple ways such as:

  • Work Manager (Best Choice)
  • Intent Service
  • Job Scheduler
  • None of those are background thread mechanisms. They run on the UI thread unless you specify otherwise. And in his code he is using a background thread. – Gabe Sechan Jul 27 '22 at 15:35
  • @GabeSechan do you mean intent service runs on Main thread ? If yes then, can you please tell me why doesn’t it block the main thread when running long tasks. I am probably implementing something else the for the last so many years. – Rahul Deep Singh Jul 28 '22 at 16:05
  • Sorry IntentService does launch a thread for worker intents. The other two do not necessarily. It's also deprecated. But none of these are appropriate for what he wants to do, which is a few seconds of processing to be done immediately on a thread, and where the process must remain open (because its pointless if the process is killed, the data he's trying to save is lost). – Gabe Sechan Jul 28 '22 at 18:07