Advertisement
BankUpload Join!

Saturday, February 7, 2015

Workaround for error EBitmapLoadingFailed on Android Lollipop

Workaround for error EBitmapLoadingFailed on Android Lollipop

Introduction

There is a bug in Delphi XE7 why Android will not boot on Lollipop (Android 5.0). In particular, they go to crash immediately after displaying the splash, because EBitmapLoadingFailed exception that is raised during the loading of the images contained in the file .fmx. 
The same application (same APK) run smoothly on Android versions prior to 5.

There are a couple of threads about it, on social-network:

Describes a workaround (which I have applied to the beta version of ColorMapp this morning) that is to load the graphic resources (TBitmap) at runtime rather than leave them embedded in the application resources (thus preventing a loaded through a call to TBitmap. LoadFromStream, which seems to be the critical point of failure).

Steps to apply the workaround:

1) Save to disk all the bitmap of each form

(Handy if you have already uploaded the pictures at design time, less useful if you are writing an application from scratch)

To simplify the process, I wrote a piece of code that iterates on the components of a form and saves all of the bitmap that is TImage.
You can look at the function of SaveAllImagesToDisk ImageDumpUnit.pas unit , found in my GitHub repository:


For example, in the event OnCreate of form I added:

{$ IFDEF mswindows}
SaveAllImagesToDisk (Self);
{$ ELSE}
LoadAllImagesFromDisk (Self);
{$ ENDIF}

Running the application on Win32 platform, you will generate a folder with subfolders images_dump (one for each form) with images saved in PNG files.
The $ ELSE branch of the compiler directive is executed for example on Android, so the Win32 application dumps and the Android application tries to dynamically load images from the storage device.

2) Remove all bitmap resources (.fmx)

The easiest (but requires to act manually on each component of your form with a bitmap) is to:
  • empty all entries of MultiResBitmap (eliminating all versions of the bitmap);
  • empty the TBitmap (eg. the properties StartValue / StopValue of TBitmapAnimation), opening the component editor and pressing the Clear key;
If you have many TBitmap and empty them manually seems impossible, you may act directly on the DFM, looking all occurrences of Bitmap. 

3) Load at run-time images corresponding

Again you can take advantage of the function LoadAllImagesFromDisk ImageDumpUnit.pas unit , taking care to call it for example in the event OnCreate of your form.

4) Add to deploy all PNG files generated in step 1

Through the deployment manager of Delphi, add the PNG file so that they are distributed with your application. Take care to indicate how RemotePath, the value 'assets / internal / images_dump /' followed by the name of the corresponding form.


5) subsidiaries have no other TBitmap

For example, I realized that the problem also with TBitmap (not just TMultiResBitmap) present in many components (eg. The TBitmapAnimation). To these I solved manually (mimicking the behavior of LoadAllImagesFromDisk) but it may make sense to automate the dump and load dynamic even those.

Conclusion

It 's all, following these steps I have solved the crash of my application XE7 ColorMapp on Android 5.0 Lollipop and currently I have a beta running on my Nexus 5.
Account to promote the beta in production just made tests on some other device.


No comments:

Post a Comment