dart_pdf icon indicating copy to clipboard operation
dart_pdf copied to clipboard

fontFromAssetBundle throw "Binding has not yet been initialized." in Isolates

Open Ayad-Ben-Saliem opened this issue 8 months ago • 3 comments

Describe the bug I'm trying to create a PDF document on a separate isolate, and I use a custom font using fontFromAssetBundle method. its works fine for the web, but when I built an Android application I got the following exception:

Binding has not yet been initialized.
The "instance" getter on the ServicesBinding binding mixin is only available once that binding has been initialized.
Typically, this is done by calling "WidgetsFlutterBinding.ensureInitialized()" or "runApp()" (the latter calls the former). Typically this call is done in the "void main()" method. The "ensureInitialized" method is idempotent; calling it multiple times is not harmful. After calling that method, the "instance" getter will return the binding.
In a test, one can call "TestWidgetsFlutterBinding.ensureInitialized()" as the first line in the test's "main()" method to initialize the binding.
If ServicesBinding is a custom binding mixin, there must also be a custom binding class, like WidgetsFlutterBinding, but that mixes in the selected binding, and that is the class that must be constructed before using the "instance" getter.

#0      BindingBase.checkInstance.<anonymous closure> (package:flutter/src/foundation/binding.dart:308:9)
#1      BindingBase.checkInstance (package:flutter/src/foundation/binding.dart:389:6)
#2      ServicesBinding.instance (package:flutter/src/services/binding.dart:56:54)
#3      PlatformAssetBundle.load (package:flutter/src/services/asset_bundle.dart:326:54)
#4      fontFromAssetBundle (package:printing/src/asset_utils.dart:77:30)
...

This is a sample of my code.

compute<Bill, Uint8List>(createPdfBill, bill);

Future<Uint8List> createPdfBill(Bill bill) async {
  final font = await fontFromAssetBundle('assets/fonts/HacenTunisia/Regular.ttf');

  final pdf = Document();

  pdf.addPage(
    Page(build: (context) {
        /* building a PDF here */
    }),
  );

  return pdf.save();
}

However, the code works fine on the web, but it didn't for the Android app.

Note 1- I added WidgetsFlutterBinding.ensureInitialized(); in main.dart.

2- I also tried to add WidgetsFlutterBinding.ensureInitialized(); on the isolate, but I got another exception UI actions are only available on root isolate.

Is this a bug in printing? How to solve/workaround this issue?

Now I execute createBill method in the main isolate to avoid this exception, but I hope this will be solved soon.

Flutter Doctor

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.13.8, on Ubuntu 22.04.3 LTS 6.2.0-35-generic, locale en_US.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Chrome - develop for the web
[✓] Linux toolchain - develop for Linux desktop
[✓] Android Studio (version 2022.3)
[✓] VS Code (version unknown)
    ✗ Unable to determine VS Code version.
[✓] Connected device (3 available)
[✓] Network resources

• No issues found!

Build platforms

  • [ ] iOS
  • [x] Android
  • [x] Browser
  • [ ] Windows
  • [ ] Linux

Build devices

  • Device: POCO F5
  • OS: Android 13 TKQ1.221114.001
  • Browser: Chrome version 118.0.5993.88 (Official Build) (64-bit)

Ayad-Ben-Saliem avatar Oct 23 '23 00:10 Ayad-Ben-Saliem

Hi, you should try initialize your own font in main isolate and then pass this new font as parameter.

that will be something like:

void main async(){
// in main isolate
  final font = await fontFromAssetBundle('assets/fonts/HacenTunisia/Regular.ttf');
  Bill bill = Bill();
  var result = Isolate.run(() async=> await createPdfBill(bill,font));
}
Future<Uint8List> createPdfBill(Bill bill, TtfFont font) async {
  final pdf = Document();

  pdf.addPage(
    Page(build: (context) {
        /* building a PDF here */
    }),
  );

  return pdf.save();
}

NurNur1 avatar Nov 10 '23 16:11 NurNur1

@NurNur1 But while it works for the web, it should work for Android too. Your answer is great as a workaround solution, but I still think that there is a bug that needs to be fixed.

Ayad-Ben-Saliem avatar Nov 16 '23 23:11 Ayad-Ben-Saliem

same problem happend for me, did you find any solution ?

SidouAbr avatar Jan 30 '24 15:01 SidouAbr