iZettle / android-html2bitmap

Generates a bitmap from html by rendering the content inside an off screen webview
MIT License
57 stars 20 forks source link

Timeout exception when rendering html #32

Closed Averus89 closed 4 years ago

Averus89 commented 5 years ago

Hi,

I'm trying to generate bitmap using 1.10 version of the library, and when trying to use this html I'm getting timeout exception.

        Bitmap bitmap = new Html2Bitmap.Builder()
                .setContext(MainApp.getAppContext())
                .setContent(WebViewContent.html(html))
                .setBitmapWidth(576)
                .build()
                .getBitmap();
E/Html2Bitmap: []
    java.util.concurrent.TimeoutException
        at java.util.concurrent.FutureTask.get(FutureTask.java:206)
        at com.izettle.html2bitmap.Html2Bitmap.getBitmap(Html2Bitmap.java:67)
        at com.izettle.html2bitmap.Html2Bitmap.getBitmap(Html2Bitmap.java:92)

Maybe this could be usefull

I/WebViewFactory: Loading com.android.chrome version 76.0.3809.132 (code 380913237)
I/cr_LibraryLoader: Time to load native libraries: 6 ms (timestamps 25-31)
I/chromium: [INFO:library_loader_hooks.cc(51)] Chromium logging enabled: level = 0, default verbosity = 0
I/cr_LibraryLoader: Expected native library version number "76.0.3809.132", actual native library version number "76.0.3809.132"
W/cr_ChildProcLH: Create a new ChildConnectionAllocator with package name = com.android.chrome, sandboxed = true
I/cr_BrowserStartup: Initializing chromium process, singleProcess=false
W/ResourceType: Failure getting entry for 0x7f130532 (t=18 e=1330) (error -2147483647) type=1400 audit(0.0:87): avc: denied { read } for name="vmstat" dev="proc" ino=4026532356 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0
W/VideoCapabilities: Unrecognized profile 2130706433 for video/avc
W/VideoCapabilities: Unrecognized profile 2130706434 for video/avc
W/VideoCapabilities: Unrecognized profile 2130706433 for video/avc
W/VideoCapabilities: Unrecognized profile 2130706434 for video/avc
W/VideoCapabilities: Unsupported mime video/divx
W/VideoCapabilities: Unsupported mime video/divx311
W/VideoCapabilities: Unsupported mime video/divx4
W/VideoCapabilities: Unrecognized profile/level 0/3 for video/mpeg2
W/VideoCapabilities: Unrecognized profile/level 0/3 for video/mpeg2
V/FA: Connection attempt already in progress
W/VideoCapabilities: Unsupported mime video/x-ms-wmv
I/chatty: uid=10099() Chrome_InProcGp identical 1 line
W/VideoCapabilities: Unsupported mime video/x-ms-wmv
W/VideoCapabilities: Unrecognized profile 2130706433 for video/avc
W/VideoCapabilities: Unrecognized profile 2130706434 for video/avc
I/VideoCapabilities: Unsupported profile 4 for video/mp4v-es
W/Utils: could not parse long range '175-174'

And the html put into the client

    <HTML>
    <HEAD>
        <style>
            body{
        vertical-align: top;
        font-family: "Roboto";
        font-weight: bold;
        font-size: 16pt;
        line-height: 1.1;
        margin:5px;
        height: 2000px;
    }
    span.bold{
        font-weight: bolder;
    }
    span.bigText{
        font-size: 20pt;
        display: block;
    }
    span.bigerText{
        font-size:  28pt;
        display: block;
    }
    span.smallText{
        font-size: 12pt;
        display: block;
    }
    span.smallerText{
        font-size: 10pt;
        display: block;
    }
    div.claimcheck{
        position:absolute;
        top: 20px;
        height:385px; width:566px;
    }
    div.rackstub{
        position:absolute;
        top:410px;
        height: 705px; width:566px;
        display: block;
    }
    div.keystub{
        display:table;
        position:absolute;
        top:1120px;
        height: 300px; width:566px;
    }
    div.windowstub{
        position: absolute;
        top:1425px;
        height: 150px; width: 566px;
    }
    div.backupclaimcheck{
        position:absolute;
        top:1580px;
        height: 410px; width:566px;
    }

            div{
        border-style: solid;
        border-width: 1px;
    }
    div.title {
        font-size: 20pt;
        text-align:center;
    }
    div.center {
        text-align:center;
    }
    div.note {
        font-size:10pt;
        text-align:center;
    }
    div.alignleft {
        text-align:left;
    }
    div.left {
        width:276px;
        float: left;
        text-align:left;
        font-weight:bold;
    }
    div.right {
        width:276px;
        float: right;
        text-align:right;
        padding-right:10px;
    }

        </style>
    </HEAD>
    <BODY>

    <!-- CLAIM CHECK -->
    <div class="claimcheck">
        <div class="note">***** THIS IS NOT A RECEIPT *****</div>
        <br />
                    <div class="title">COMPANY NAME</div>
        <div class="center">
            COMPANY ST <br />
            COMPANY ADDRESS2, AU 00000 <br />
             LICENSE# XYZ12345  <br />
        </div>
        <br />
        <div class="center">TICKET #202393</div>
        <br />
        <div class="alignleft">202393 WHITE LEXUS HJZ5567(NY) Damage: --</div>
        <br />
        <br />
        <div class="left">IN:</div>
        <div class="right">08/02/19 1:33 PM</div>
            <div class="left">OUT:</div>
        <div class="right">09/23/19 3:23 PM</div>
            <div class="left">STAY:</div>
        <div class="right">1 MTH, 21 DAYS, 1 HR, 50 MINS</div>
        </div>

    <!-- RACK STUB -->
    <div class="rackstub">
                <div class="left">RATE:</div>
                <div class="right">1 @ $0.48</div>
                <div class="left">CHARGE TOTAL:</div>
                <div class="right">$0.48</div>

                <div class="left">TAX Rate: 10.375%</div>
                <div class="right">$0.05</div>
                    <div class="left">TOTAL</div>
                <div class="right">$0.53</div>
            <br />
            <br />
            <div class="center">cash PAYMENT </div>
            <div class="left">AMOUNT TENDERED</div>
    <div class="right">$0.53</div>
    <div class="left">TOTAL PAYMENT</div>
    <div class="right">$0.53</div>
    <div class="left">CHANGE DUE</div>
    <div class="right">$0.00</div>

        <br />
        <div class="note">MDC 09/23/19 3:23 PM 0333-0020-00001052</div>
        <br />
        <br />
        <div class="center">
            THANK YOU<br />
            COMPANY NAME <br />
        </div>
        <br />
        <div class="note" >***** THIS IS NOT A RECEIPT *****</div>
    </div>

    <!-- KEY STUB -->
    <div class="keystub">

    </div>

    <!-- WINDOW STUB -->
    <div class="windowstub">

    </div>

    <!-- BACKUP CLAIM CHECK -->
    <div class="backupclaimcheck">

    </div>

    </BODY>
    </HTML>
erikeelde commented 5 years ago

It doesn't look like the html has anything crazy in it that should end up with a timeoutException. Did you try increasing the timeouts of the bitmap generation to see if that makes any difference? Does that html work if inputted into the test application from the releases-page?

Averus89 commented 5 years ago

I've tried to increase timeout to 30s, 1 min, 3 mins, 5 mins - still got timeout exception and blocked my UI for the time - got ANR few times during that timeframes. This html loads perfectly in WebView in UI, and also I've noticed if I generate it in WebView in the activity first - doesn't get timeout, so the page must be rendered and cached somewhere.

I've managed to reuse some of the code in the library to create simplified version with 1s timeout after 100% progress onPageLoad - this renders bitmap correctly. I've found on the stackoverflow that the 100% progress refers to data read into WebView, and rendering it's another case indepentent of that value.

erikeelde commented 5 years ago

Ah.. so if you got an ANR you are probably calling the library from the mainThread (as the library tries to not lock up the main thread more than necessary). The library does however need to post callbacks on the main thread as it's a requirement by the WebView on android. Potentially what could be happening is that if you are locking the main thread the library is unable to send those callbacks and hence you get stuck in a deadlock until the timeout occurs.

Try to move your invocation of "generateBitmap" off the mainThread and see if it works better.

Also please try the provided test-application from the releases pages as that might be a way for you to start out with working code and mutating it into what you need.

erikeelde commented 4 years ago

@BeeeQueue Could you close this one too? :)

beeequeue commented 4 years ago

Would you be up for having the project transferred to your profile? I can ask around to see if I can get it done

erikeelde commented 4 years ago

I would be open to it. Your asking around would be appreciated. :)