Static Binding Generator - What is it good for?


We are excited to show you a new feature that comes with the 2.0 release. A tool called “Static Binding Generator” or SBG for short. Good news is, it’s enabled by default and you don’t need to do anything special in order to take advantage of its functionality.

What can I use the Static Binding Generator for?

A common scenario in android development is being able to add a custom activity and navigate to it.

There are also several very popular libraries that requires this functionality. See for example the native YouTube SDKs. Here is a snippet from their documentation:

A view for displaying YouTube videos. Using this View directly is an alternative to using the YouTubePlayerFragment. If you choose to use this view directly, your activity needs to extend YouTubeBaseActivity.

The way you add a custom Activity or a class in native android application, is to declare it in the AndroidManifest.xml file, as well as to create the declared class. The same goes not just for activities, but for any application component.

Prior to the 2.0 release in NativeScript you couldn’t declare custom JavaScript classes in the AndroidManifest.xml.

Thanks to the SBG, now you can have custom Java classes and all application components, declared in the AndroidManifest.xml file. That enables the full native functionality already present in android. To make things clearer, let’s give a common example

How to add a custom activity to a NativeScript project?

Step1 - declare the Activity in the AndroidManifest.xml file
As we saw the Activity is an android class that needs to be declared in the AndroidManifest.xml, so let’s do that first.

  • Go to app/App_Resources/Android/AndroidManifest.xml and add an activity tag, so the xml file look something like this:

file: "app/App_Resources/Android/AndroidManifest.xml"

<manifest …>
    <application … >
        <activity android:name=”com.tns.MyActivity” />
    </application>
</manifest>

 

NOTE: Notice the “MyActivity” class we just declared needs to be put in at least one namespace, or else it won’t be recognized as a custom class.

Step2: Provide the actual class implementation
Now that we have declared the custom activity in the manifest we need to provide the actual class implementation.

  • Create that custom js class that will contain the logic in the declared activity: app/MyActivity.js.

NOTE: The JavaScript file can be named any way you like, it is necessary however to place it somewhere  inside the "app/" folder. I name it the same way, as the declared class in the manifest only for the sake of consistency.

A minimal implementation of this file looks like:

Javascript file: "app/MyActivity.js" 

android.app.Activity.extend("com.tns.MyActivity", {
    onCreate: function (bundle) {
        this.super.onCreate(bundle);
    }
});

 

TypeScript file: "app/MyActivity.ts"

@JavaProxy("com.tns.MyActivity")
class MyActivity extends android.app.Activity {
    protected onCreate(bundle) {
        super.onCreate(bundle);
    }
};

 

NOTE: Notice that the activity we extend is a native activity - android.app.Activity. Here is the place to choose what native class we want to extend. We could also inherit android.support.v7.app.AppCompatActivity with the same result, and that’s a great feature we didn’t have until 2.0.

NOTE: The name of the extend and the activity name, declared in the AndroidManifest.xml, need to be the same: com.tns.MyActivity.

That’s it. You now control your activity like you would in a native android app, but through JavaScript only.

Demo projects

As mentioned some common application components that take advantage of the SBG are activities, applications and widgets. Here are some examples with common scenarios that take advantage of the SBG:

NOTE: Both examples follow the recommended android way of enabling widgets and multidex support.

Performance boost

There is a bonus that comes with the SBG, performance-wise. There is a significant boost on the initial loading time of the application. Here are the numbers for the default NativeScript app, ran on Nexus 5.

NUMBER  BEFORE AFTER DIFERENCE
 1. 2s694ms  1s901ms  -793
 2. 1s610ms 1s579ms  -31
 3. 1s622ms 1s547ms  -75
 4. 1s657ms 1s603ms  -54

Thanks to the SBG, all class generation is done at build-time, enabling your application to load faster.

What happens behind the scenes?

Project structure after build:

+--app/
|    +--App_Resources/
|    |    +--Android/
|    |    +--AndroidManifest.xml (1)
|    |
|    +--...
|    |
|    |--MyActivity.js  (2)
+--...
+--platforms/
    +--android/
        +--...
        +--src/
            +--main/
                +--assets/
                |   +--app/
                |   +--...
                |
                +--java/ (2)
                    +--com
                        +--tns
                            +--MyActivity.java (3)

 

  1. AndroidManifest.xml file you can edit: add activities, application and other application components

  2. The JavaScript class you declare in the AndroidManifest.xml

  3. The file generated by the SBG, that serves as a proxy for your JavaScript class MyActivity.js

  • On build time the JavaScript files you created will be analyzed and a java proxy will be created for "app/MyActivity.js", it will also be generated where you specified: com/tns/MyActivity.java

  • The build will take care of compiling the generated java file com/tns/MyActivity.java (3), and packing it into the application.

  • On install time the AndroidManifest.xml, which you edited, will be able to use the newly generated and compiled MyActivity.class file and will invoke its onCreate method, which in turn will call your JavaScript implementation file /app/MyActivity.js and its overridden onCreate method.


Thanks to the SBG you can now have automatically generated JavaScript proxies, in the form of Java classes, that can be declared in the AndroidManifest.xml file.

Now anyone keen to implement a YouTube player plugin for NativeScript? :)


Author

Plamen Petkov

Comments


Comments are disabled in preview mode.
NativeScript is licensed under the Apache 2.0 license
© 2020 All Rights Reserved.