tvbarthel / BlurDialogFragment

Library project to display DialogFragment with a blur effect.
Apache License 2.0
2.09k stars 337 forks source link

Canvas: trying to use a recycled bitmap #53

Open kitek opened 8 years ago

kitek commented 8 years ago

Hi, i'm using SupportBlurDialogFragment and sometimes i got exception (probably when user rotate device):

FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:300)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
    at java.util.concurrent.FutureTask.run(FutureTask.java:242)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:841)
 Caused by: java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@420c9438
    at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1084)
    at android.graphics.Canvas.drawBitmap(Canvas.java:1170)
    at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine.blur(BlurDialogEngine.java:390)
    at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine.access$300(BlurDialogEngine.java:41)
    at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine$BlurAsyncTask.doInBackground(BlurDialogEngine.java:567)
    at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine$BlurAsyncTask.doInBackground(BlurDialogEngine.java:524)
    at android.os.AsyncTask$2.call(AsyncTask.java:288)
tbarthel-fr commented 8 years ago

Hi @kitek (=

Could you give us more insight in order to fix it?

May I ask you which version of the library you are using? Android version of the device?

We could avoid the crash by checking if the bitmap has been recycled but it won't fix the real source of the issue.

Have you find a way to reproduce it?

ghost commented 8 years ago

Hello, I've got the same Problem. I'm using version 2.1.5.

If the DialogFragment is shown and the device rotated the app crashes.

FATAL EXCEPTION: AsyncTask #6 Process: de.tu_berlin.qu.pflegetab, PID: 10001 An error occured while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:300) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) at java.util.concurrent.FutureTask.setException(FutureTask.java:222) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:831) Caused by: java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@374313e5 at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1225) at android.graphics.Canvas.drawBitmap(Canvas.java:1312) at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine.blur(BlurDialogEngine.java:390) at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine.access$300(BlurDialogEngine.java:41) at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine$BlurAsyncTask.doInBackground(BlurDialogEngine.java:567) at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine$BlurAsyncTask.doInBackground(BlurDialogEngine.java:524) at android.os.AsyncTask$2.call(AsyncTask.java:288) at java.util.concurrent.FutureTask.run(FutureTask.java:237) ... 4 more

The content of my Dialog is a webview.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="50dp" android:layout_marginRight="50dp" android:layout_marginBottom="20dp" android:layout_marginTop="10dp"> <WebView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/webView3" /> `

edit: Well, the error only appears on my galaxy tab s2 9.7 and not on my huawei smartphone .. weird

happylishang commented 8 years ago

maybe,you could add this in activiy, to avoid DialogFragment is added twice

    @Override
    public void onCreate(Bundle savedInstanceState) {
        if (savedInstanceState != null) {
            savedInstanceState.putParcelable("android:support:fragments", null);
        }
        super.onCreate(savedInstanceState);
    }
pcudek commented 8 years ago

Have the same problem with class extends SupportBlurDialogFragment Probably it is connected with creating blure It happends rarely Android 4.2.2

FATAL EXCEPTION: AsyncTask #3 java.lang.RuntimeException: An error occured while executing doInBackground() android.os.AsyncTask$3.done(AsyncTask.java:299) java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352) java.util.concurrent.FutureTask.setException(FutureTask.java:219) java.util.concurrent.FutureTask.run(FutureTask.java:239) android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573) at java.lang.Thread.run(Thread.java:856) Caused by: java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@422ed090 at android.graphics.Canvas.throwIfRecycled(Canvas.java:1026) at android.graphics.Canvas.drawBitmap(Canvas.java:1096) at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine.blur(BlurDialogEngine.java:390) at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine.access$300(BlurDialogEngine.java:41) at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine$BlurAsyncTask.doInBackground(BlurDialogEngine.java:567) at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine$BlurAsyncTask.doInBackground(BlurDialogEngine.java:524) at android.os.AsyncTask$2.call(AsyncTask.java:287) at java.util.concurrent.FutureTask.run(FutureTask.java:234)

timo-meijer commented 8 years ago

Same issue here

crash.txt

markmooibroek commented 8 years ago

I have the same problem here. Do you need anything to pinpoint this issue faster?

timo-meijer commented 8 years ago

I think I might have fixed this issue by setting the following to true: isRenderScriptEnable().

sekomod commented 8 years ago

I have the same problem and issue is here. BlurDialogFrament Lib Version: 2.2.0 OS: Android 4.4.2 OS: Android 5.1.1 OS: Android 6.0.1 Device: HTC Desire 620G dual sim Device: Sony C6903 Device: SM-G900FQ Devices are not rooted Fatal Exception: java.lang.RuntimeException: An error occured while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:300) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) at java.util.concurrent.FutureTask.setException(FutureTask.java:222) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:841) Caused by java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@4313d860 at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1084) at android.graphics.Canvas.drawBitmap(Canvas.java:1170) at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine.blur(BlurDialogEngine.java:416) at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine.access$400(BlurDialogEngine.java:42) at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine$BlurAsyncTask.doInBackground(BlurDialogEngine.java:593) at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine$BlurAsyncTask.doInBackground(BlurDialogEngine.java:550) at android.os.AsyncTask$2.call(AsyncTask.java:288) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:841)

shumin0809 commented 7 years ago

Any solution for this bug? Thanks.

pcudek commented 7 years ago

I added to build.gradle defaultConfig {

    renderscriptTargetApi 17
    renderscriptSupportModeEnabled true
}

and so far no troubles

2016-10-14 22:33 GMT+02:00 shumin gao notifications@github.com:

Any solution for this bug? Thanks.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/tvbarthel/BlurDialogFragment/issues/53#issuecomment-253912079, or mute the thread https://github.com/notifications/unsubscribe-auth/ABN-b1uVzJPNzpBWpoFYyzzdyqkp-0bQks5qz-cJgaJpZM4HOPy0 .

simmikava commented 7 years ago

Hi,

I tried solution provided by pcudek but I am still experiencing the same issue. Any other help will be appreciated.

I am using 2.2.0 version.

vbarthel-fr commented 7 years ago

@tbarthel-fr could you have a look?

tbarthel-fr commented 7 years ago

Sadly I can't reproduce the crash with a sample app compiled from the master|develop branch.

We could use defensive programming and check if the background bitmap isn't recycled before calling blur :

            if (!isCancelled() && !mBackground.isRecycled()) {
                blur(mBackground, mBackgroundView);
            } else {
                return null;
            }

it won't crash but it will let the engine into an unexpected state (which could lead to further crashes later) that's why I would rather want to find when the bitmap is recycled...

Could anyone with this issue add more insights on how reproducing the crash?

Have you experiment this crash with the sample app?

Are you somehow dealing with the drawing cache of the holding activity on your side? Causing the drawing cache to be destroyed would lead to this crash since it recycles the bitmap used by the BlurDialogEngine.

simmikava commented 7 years ago

@tbarthel-fr Not sure if this information may help you in any way, but this is an observation. If the dialog fragments width and height = match_parent, this issue occurs. If the dialog fragments are smaller than that, the BlurDialogFragment works perfectly fine.

tbarthel-fr commented 7 years ago

Hi @simmikava (:

Thanks for trying to add more input to this issue!

Hope I will be able to reproduce this crash now.

When you wrote "this issue occurs", do you meant it happens every time or still sparsely?

simmikava commented 7 years ago

@tbarthel-fr Well in my case I am experiencing this issue with 3 dialog fragments / layouts.

  1. The parent item in the dialog fragment's layout is Relative Layout with Height and Width = Match_Parent
  2. The parent item in the dialog fragment's layout is Linear Layout, Height and Width = Match_Parent
  3. The parent item in the dialog fragment's layout is Linear Layout, Width = Match_Parent, Height = Wrap_Content but gravity has been set to top - using getDialog().getWindow() parameters.

So I had to remove BlurDialogFragment for these dialog fragments and it was consistent in nature for above mentioned ones. Initially it was happening occasionally, but later on the frequency was seen quite often. So every time would not be right to mention, but yes frequency was definitely higher than sparse.

Hope this helps! :)

tbarthel-fr commented 7 years ago

Hi @simmikava (=

Thanks for all these details and sorry for the late late answer :X

I'm still not reproducing this using the sample app and the configuration you mentioned.

Could you try to use the dialog which trigger this unexpected bitmap recycling with the sample app on a specific branch so that I could try to identify the source of concern?

fincode commented 7 years ago

Hello, may be stacktrace can help you: lib version: 2.1.5

Android: 5.1 Manufacturer: HOMTOM Model: HT6 CrashReporter Key: F3E32113-A791-B34C-BF77-1D9516388687D79871A9 Date: Wed Dec 28 13:31:10 GMT+06:00 2016

java.lang.RuntimeException: An error occured while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:304) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) at java.util.concurrent.FutureTask.setException(FutureTask.java:222) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:818) Caused by: java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@16bc70e2 at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1282) at android.graphics.Canvas.drawBitmap(Canvas.java:1369) at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine.blur(BlurDialogEngine.java:390) at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine.access$300(BlurDialogEngine.java:41) at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine$BlurAsyncTask.doInBackground(BlurDialogEngine.java:567) at fr.tvbarthel.lib.blurdialogfragment.BlurDialogEngine$BlurAsyncTask.doInBackground(BlurDialogEngine.java:524) at android.os.AsyncTask$2.call(AsyncTask.java:292) at java.util.concurrent.FutureTask.run(FutureTask.java:237)

tbarthel-fr commented 7 years ago

Thanks (=

I guess the stack is well known now and the exception could be avoided using defensive programming (aka if(bitmap.isRecycled()) but it won't fix the issue (which is the bitmap used here must have no reason to be recycled...) and could bring other worst behaviour (later crash due to inconsistence state or visual bug for the user) since it's clearly an unexpected state.

What we need now is a way to reproduce it and i'm still not able to do it using the sample app and another app using the library :/

Does anyone who is experiencing this crash have a project reproducing it?

tbarthel-fr commented 7 years ago

Some update here: since the bitmap is retrieved through getDrawingCache(), it could be recycled internally or from another user of the drawing cache.

For instance, a simple call on destroyDrawingCache during the blur allow us to reproduce this stack trace.

We are still investigating but a solution could be to use our own bitmap instead of relying on the drawing cache.

vbarthel-fr commented 7 years ago

Just to keep you updated about this issue.

We are currently working on a new way of getting the bitmap of the root view. It will no longer use the View.getDrawingCache(). It should also reduce the memory usage =)

You can expect a beta of this new version in the coming weeks.

fabriziogueli commented 7 years ago

@vbarthel-fr Any news about this issue?

Thx

pcg92 commented 7 years ago

My solution:

    @Override public void onPause() {
        super.onPause();
        //set rotation to sensor dependent
        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
    }

    @Override
    public void onResume() {
        super.onResume();
        getActivity().setRequestedOrientation(getResources().getConfiguration().orientation);
        mBlurEngine.onResume(getRetainInstance());
    }
ct-taras commented 6 years ago

Is this issue fixed by now?

hivian commented 6 years ago

No.

kam520c commented 5 years ago

Probably I know how to reproduce it. 1.new a BlurDialogFragment A and show it. 2.create a new BlurDialogFragment B and show it without dismiss A. 3.close Dialog B and then close A. 4.create BlurDialogFragment A and show it again. 5.create a new BlurDialogFragment B again and show it without dismiss A. 6.then crash. You should try over and over again if you dont crash . You should do it quickly,before the end of the mathod blur() execution.You can try it in genymotion.

jonashoc commented 4 years ago

Still no fix for this? Does anyone know of another library that works like this, but does not crash and is consistently updated?