wasabia / three_dart

three.js rewrite by Dart, Dart 3D library. an easy to use, lightweight, cross-platform, general purpose 3D library.
MIT License
444 stars 77 forks source link

None of the example works in Release mode in Android #136

Open hasnentai opened 11 months ago

hasnentai commented 11 months ago

I had built a huge app using three.dart and all was working fine under debug mode then I tried a release build for Android and it does not show up anything on the screen. It's all black and no Textures. @wasabia Can you help me with the issue?

dependencies:
  flutter:
    sdk: flutter
  three_dart: ^0.0.14
  three_dart_jsm: ^0.0.9
  flutter_gl: ^0.0.21

output of flutter doctor

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.10.3, on macOS 13.4.1 22F82 darwin-arm64, locale en-IN)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 14.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.1)
[✓] VS Code (version 1.80.0)
[✓] VS Code (version 1.71.0)
[✓] Connected device (3 available)
[✓] Network resources

• No issues found!
hasnentai commented 11 months ago

cc : @Knightro63

Knightro63 commented 11 months ago

Hi @hasnentai,

This can happen for a multiple of reasons, but mainly has to do with the AndroidManifest.xml file. Can you compare yours to the example one to see if there is a difference.

Make sure it contains:

android:allowBackup="false"
tools:replace="android:label,android:allowBackup"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"

If that does not fix the issue add splits to your android/app/build.gradle file under andriod.

    splits {
        abi {
            reset()
            enable true
            universalApk true  // If true, also generate a universal APK
            include "armeabi-v7a", "x86", "arm64-v8a"
        }
    }

Also make sure that you have a signing config in that file if you have it in release mode. If not this could cause some issues as well.

If you still have a issue add proguard rules to build types. You will need to make a txt file for this.

    buildTypes {
        release {
            // TODO: Add your own signing config for the release build.
            // Signing with the debug keys for now, so `flutter run --release` works.
            signingConfig signingConfigs.release
            minifyEnabled true

            //useProguard true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

proguard-android.txt

## Flutter wrapper
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.**  { *; }
-keep class io.flutter.util.**  { *; }
-keep class io.flutter.view.**  { *; }
-keep class io.flutter.**  { *; }
-keep class io.flutter.plugins.**  { *; }
-dontwarn io.flutter.embedding.**

Another reason this could be happening is you have a BackgroundHandler that is interfering with it.

Is this happening when you are running flutter run -d "deviceID" --release or after you have placed it on the store? Are you testing release mode on simulator or actual device?

Hope this helps.

hasnentai commented 11 months ago

it is happening when I am running flutter run -d "deviceID" --release and even after building a singing config with the above solutions it's the same. I can see the logs of the verbose which are written for the texture but my screen stays black.

I don't think so we can run release mode on simulator so its obvious I am running on real device @Knightro63 Did you try to release the build in Android?

This is so scary it does work sometimes and sometimes it does not 👎🏻 . it's been more than 48 hours I am doing the same thing now. If ran an app for 10 time its just work for one time. which means there is something wrong with BackgroundHandler

I have the same issue with the repo of yours. https://github.com/Knightro63/three_dart @Knightro63 If you try to run your example app like this

runApp(MaterialApp(home: multi_views(fileName: 'multi_views'),));

It will work sometimes and It will not work the other time I run the app

hasnentai commented 11 months ago

So here is my finding. If I run an app and have a single page which is displaying the texture directly then it will not show up anything. Then I created the same example app which has two pages, 1 is for listing the example and another one is for the texture of three.dart and then it worked. which means the native thread needs some delay to display or attached the view of three.dart to flutter texture or may something like that. So to make this work what I did is as below.

 body: Builder(builder: (context) {
        Future.delayed(
            const Duration(milliseconds: 100), () => {initSize(context)});

I added a delay to make this work consistent.

hasnentai commented 11 months ago

Also It's Overriding the flutter logo to native android logo. What can be done for that ?

Knightro63 commented 11 months ago

Hi @hasnentai,

I a experienced the same issue you are with runApp(MaterialApp(home: multi_views(fileName: 'multi_views'),));. The issue is that flutter_gl is loading async and the views are loading before flutter_gl is ready. To fix this put this in a FutureBuilder.

class _MyAppState extends State<multi_views> {

  THREE.WebGLRenderer? renderer;
  bool show = false;
  var three3dRender = FlutterGlPlugin();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  Future<bool> init() async {
    if(!kIsWeb) {
      await three3dRender.initialize(options: {"width": 1024, "height": 1024, "dpr": 1.0});
      await three3dRender.prepareContext();

      Map<String, dynamic> _options = {
        "width": 1024,
        "height": 1024,
        "gl": three3dRender.gl,
        "antialias": true,
      };
      renderer = THREE.WebGLRenderer(_options);
      renderer!.autoClear = true;
    }
    return true;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.fileName),
      ),
      body: FutureBuilder<bool>(
        future: init(),
        builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
          if (!snapshot.hasData) {
            return CircularProgressIndicator();
          }
          else{
            return _build(context);
          }
        }
      ),
    );

  }

  Widget _build(BuildContext context) {
    return Column(
      children: [
        multi_views1(renderer: renderer),
        Container(height: 2, color: Colors.red,),
        multi_views2(renderer: renderer)
      ],
    );
  }

}

To fix the overriding of the flutter logo you can use flutter_icons to put your own icon instead.

dev_dependencies:
  flutter_lints: 2.0.1
  flutter_launcher_icons: ^0.13.1
  flutter_test:
    sdk: flutter

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
flutter_icons:
  android: true
  ios: false
  min_sdk_android: 21 # android min sdk min:16, default 21
  image_path_android: "path/to/image.png"
  adaptive_icon_background: "#hexCode"
  adaptive_icon_foreground: "path/to/image.png"
  image_path_ios: "path/to/image.png"
  web:
    generate: false
    image_path: "path/to/image.png"
    background_color: "#hexcode"
    theme_color: "#hexcode"
  windows:
    generate: false
    image_path: "path/to/image.png"
    icon_size: 48 # min:48, max:256, default: 48
  macos:
    generate: false
    image_path:"path/to/image.png"

Then run flutter pub get flutter pub run flutter_launcher_icons

hasnentai commented 11 months ago

Hi @Knightro63, Can you update any of the example of your repo with the above solution? I am getting stuck somewhere in flow of scene.

Knightro63 commented 11 months ago

Hi @hasnentai,

I edited multi_views in the examples in my repo to represent the code above. I moved them around so check the others folder. I also added a small example game and some physics examples.

hasnentai commented 11 months ago

Thank you @Knightro63

hasnentai commented 11 months ago

I hope this will be fix in the next release keeping it open until its fixed