Alibaba’s Kraken claims that the ability to render Web forms directly with Flutter not only makes it dynamic but also performs very well, which is equivalent to a small browser, so he immediately tried it.

Flutter: 2.0.0 OS: Linux Kraken: main@77d74a62Copy the code

Kraken does not currently support Dart sound NULL Safety, but it runs in compatible mode.

Error input ‘… Chai :^2.9’, it took a long time to find out that NPM must use the source of Taobao, which is solved by NRM. If you don’t do web non-front-end development, you will definitely be confused.

This was followed by a script error where the Android SDK was nowhere to be found:

Error [ERR_UNHANDLED_ERROR]: Unhandled error. ({
  uid: 2,
  name: 'build-android-kraken-lib',
  branch: false,
  error: Error: ENOENT: no such file or directory, scandir '/Users/lindeer/Library/Android/sdk/ndk'
      at Object.readdirSync (fs.js:1021:3)
      at /Users/lindeer/WorkPlace/flutter/projects/kraken/scripts/tasks.js:399:25
      at build-android-kraken-lib (/Users/lindeer/WorkPlace/flutter/projects/kraken/node_modules/undertaker/lib/set-task.js:13:15)
      at bound (domain.js:413:15)
      at runBound (domain.js:424:12)
      at asyncRunner (/Users/lindeer/WorkPlace/flutter/projects/kraken/node_modules/async-done/index.js:55:18)
      at processTicksAndRejections (internal/process/task_queues.js:75:11) {
    errno: -2,
    syscall: 'scandir',
    code: 'ENOENT',
    path: '/Users/lindeer/Library/Android/sdk/ndk',
    domainThrown: true
  },
  duration: [ 0, 1176206 ],
  time: 1617778189523
})
Copy the code

Needless to say, this is confusing for non-Android developers too; Because the original script assumes that the android SDK directory in the $HOME/Library/android SDK, but in fact directory should take the environment variable $ANDROID_HOME or $ANDROID_SDK_DIR:

diff --git a/scripts/tasks.js b/scripts/tasks.js
index 499d98a6.. 20690042, 100644,
--- a/scripts/tasks.js
+++ b/scripts/tasks.js
@ @ + 391-391, 6, 8 @ @ task('build-android-kraken-lib', (done) => {
 
   if (platform == 'win32') {
     androidHome = path.join(process.env.LOCALAPPDATA, 'Android\\Sdk');
+ } else if (platform == 'linux') {
+ androidHome = process.env.ANDROID_HOME;
   } else {
     androidHome = path.join(process.env.HOME, 'Library/Android/sdk')
   }
Copy the code

By the way, since NDK is used, it is also necessary to install NDK in advance. The version is over 20.0.5594570. Install NDK:

$ANDROID_HOME/tools/bin/sdkmanager "ndk; 20.0.5594570"Copy the code

Finally there should be binary command dk-build under $ANDROID_HOME/ NDK /20.0.5594570/

Before running the NPM run build:bridge: Android command on the official website, it is best to make the following changes. The main function is to change the repository address of the package, similar to the NPM change source, otherwise it is very easy to get stuck in the download link, which makes people very mad. If you are not familiar with Android development, it is easy to be confused. Cmake () : cmake () : cmake ();

diff --git a/kraken/android/gradle/wrapper/gradle-wrapper.properties b/kraken/android/gradle/wrapper/gradle-wrapper.properties
index 01a286e9.. 41ff4cf2 100644
--- a/kraken/android/gradle/wrapper/gradle-wrapper.properties
+++ b/kraken/android/gradle/wrapper/gradle-wrapper.properties
@ @ - 2, 4 + 2, 4 @ @ distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
- distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
+ distributionUrl=https\://downloads.gradle-dn.com/artifactory/appproduct_dev_local/gradle/gradle-5.6.4-all.zip
diff --git a/kraken/example/android/build.gradle b/kraken/example/android/build.gradle
index e0d7ae2c.. 93782f98 100644
--- a/kraken/example/android/build.gradle
+++ b/kraken/example/android/build.gradle
@ @ 1, 7 + 1, 7 @ @
 buildscript {
     repositories {
- google()
- jcenter()
+ maven { url 'https://maven.aliyun.com/repository/google' }
+ maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
     }
 
     dependencies {
@ @ - 11, 8 + 11, 8 @ @ buildscript {
 
 allprojects {
     repositories {
- google()
- jcenter()
+ maven { url 'https://maven.aliyun.com/repository/google' }
+ maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }}}diff --git a/kraken/example/android/gradle/wrapper/gradle-wrapper.properties b/kraken/example/android/gradle/wrapper/gradle-wrapper.properties
index 296b146b.. 39aaae73 100644
--- a/kraken/example/android/gradle/wrapper/gradle-wrapper.properties
+++ b/kraken/example/android/gradle/wrapper/gradle-wrapper.properties
@ @ - 3, 4 + 3, 4 @ @ distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
- distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
+ distributionUrl=https\://downloads.gradle-dn.com/artifactory/appproduct_dev_local/gradle/gradle-5.6.4-all.zip

diff --git a/bridge/CMakeLists.txt b/bridge/CMakeLists.txt
index 5d00989b.. d5c6816e 100644
--- a/bridge/CMakeLists.txt
+++ b/bridge/CMakeLists.txt
@ @ + 199-199, 7, 7 @ @ target_include_directories(kraken PRIVATE
   ${CMAKE_CURRENT_SOURCE_DIR} PUBLIC ./include)
 target_link_libraries(kraken PRIVATE ${BRIDGE_LINK_LIBS})
 
-if (${CMAKE_BUILD_TYPE} STREQUAL "release" OR ${CMAKE_BUILD_TYPE} STREQUAL "relwithdebinfo")
+if ((${CMAKE_BUILD_TYPE} STREQUAL "release") OR (${CMAKE_BUILD_TYPE} STREQUAL "relwithdebinfo"))
   ## http://ptspts.blogspot.com/2013/12/how-to-make-smaller-c-and-c-binaries.html
   ### remove dynamic_cast and exceptions
   target_compile_options(kraken PRIVATE -fno-exceptions -fvisibility=hidden)
Copy the code

Kraken’s example is a good example to run

$ flutter devices 3 connected devices: Pixel (Mobile) • FA69G0304769 • Android-ARM64 • Android 10 (API 29) Linux (Desktop) • Linux • Linux-X64 • Linux Chrome • Chrome • web-javascript • Google Chrome 87.0.4280.88 $CD kraken/example $flutter run -v -d FA69G0304769Copy the code

-d was added to indicate that Flutter now supports multiple devices. Sometimes, flutter automatically selects web or desktop, and console output is confused about flutter development that is not familiar with. -v displays the details of the compilation process in detail, and facilitates the location of errors. For example, flutter2.0 will report the following error but may output nothing on the console:

[        ]  - provide a 'noSuchMethod' implementation.
[        ] class ScrollPositionWithSingleContext extends ScrollPosition implements ScrollActivityDelegate {
[        ]       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[        ] /opt/programs/flutter/packages/flutter/lib/src/rendering/viewport_offset.dart:96:12: Context: 'ViewportOffset.hasPixels' is
defined here.
[        ]   bool get hasPixels;
[        ]            ^^^^^^^^^
[ +302 ms] [
Copy the code

The changes are as follows:

diff --git a/kraken/lib/src/gesture/scroll_position_with_single_context.dart b/kraken/lib/src/gesture/scroll_position_with_single_context.dart
index 29ffe2af.. 0717d321 100644
--- a/kraken/lib/src/gesture/scroll_position_with_single_context.dart
+++ b/kraken/lib/src/gesture/scroll_position_with_single_context.dart
@ @ + 74-74, 6, 9 @ @ class ScrollPositionWithSingleContext extends ScrollPosition implements ScrollAc
   @override
   AxisDirection get axisDirection => context.axisDirection;
 
+ @override
+ bool get hasPixels => false;
+
   @override
   double setPixels(double newPixels) {
     assert(activity.isScrolling);
Copy the code

You should be able to compile successfully and run after going through the three fields of confusionkraken_exampleOn the device, the running example is a native JS filekraken/example/assets/bundle.jsDevTools of flutter can be used to see that two text objects generated by flutter are flutter controls:

However, entering the sample URL in the intro article didn’t work at all! Error:

[+14652 ms] E/flutter (21723): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: NoSuchMethodError: The method
'evalBundle' was called on null.
[        ] E/flutter (21723): Receiver: null
[        ] E/flutter (21723): Tried calling: evalBundle()
[        ] E/flutter (21723): #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
[        ] E/flutter (21723): #1      _evalBundle (package:kraken/widget.dart:243:22)
[        ] E/flutter (21723): #2      Kraken.loadURL (package:kraken/widget.dart:75:5)
[        ] E/flutter (21723): <asynchronous suspension>
[        ] E/flutter (21723):
Copy the code

Its controller is a getter that looks like a cache:

   KrakenController get controller {
     return KrakenController.getControllerOfName(shortHash(this));
   }
Copy the code

Waiting for async to come back will be null. Holding will not work either

diff --git a/kraken/lib/widget.dart b/kraken/lib/widget.dart
index b77f7de4.. 5daeedff 100644
--- a/kraken/lib/widget.dart
+++ b/kraken/lib/widget.dart
   loadURL(String bundleURL) async {
     if (bundleURL == null) return;
- await controller.unload();
- await controller.loadBundle(
+ final c = controller;
+ print("--------0 loadURL: $bundleURL");
+ await c.unload();
+ print("--------1 loadURL: $bundleURL");
+ await c.loadBundle(
       bundleURL: bundleURL
     );
- _evalBundle(controller, animationController);
+ print("--------2 loadURL: $bundleURL");
+ _evalBundle(c, animationController);
   }
Copy the code

Is the usage incorrect, if directly executes the requested js text? Error:

[+16992 ms] E/flutter (22311): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: NoSuchMethodError: The method 'unload'
was called on null.
[        ] E/flutter (22311): Receiver: null
[        ] E/flutter (22311): Tried calling: unload()
[        ] E/flutter (22311): #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
[        ] E/flutter (22311): #1      Kraken.loadContent (package:kraken/widget.dart:62:22)
[        ] E/flutter (22311): #2      _MyHomePageState.build.<anonymous closure> (package:kraken_example/main.dart:65:24)
[        ] E/flutter (22311): <asynchronous suspension>
[        ] E/flutter (22311):
Copy the code

It’s hard to say if flutter2.0 has caused some controls to behave differently. There seems to be a lot of adaptation work to be done and there is no way to experience it at the moment. ! For me, I didn’t want to know too many details at first, but it was so hard to get started and see the effect immediately…

These open source KPIs in China have such problems. The documentation is not clear and too many presupposed preconditions are unfriendly to developers. It’s not even running tests right now it’s just fucking open source. Open it up. Open your fucking ass.