2

So my manager seems to think that converting an app from 2 fully native iOS and Android apps, to one cross-platform angular/nativecript app is a straightforward task (it sounds like a terrible idea to me). Im trying to research the effort required to do this. Ive created a helloworld nativescript app and im trying to see what the best way of integrating existing native code into a nativescript app is (basically i want to have access to my native webservice functions). My knowledge on this subject is severely limited.

Ive seen there is a way to make your own native packages that can be used, but this seems like it would be way to much effort and cumbersome/messy. Is there no way to just access a custom native java object inside nativescript? for example:

//Java
package com.tns;

public class TestObject {
    public String doSomething () {
        return "hello";
    }
}

//Nativescript
import { Component } from "@angular/core";

declare var com: any

@Component({
  selector: "my-app",
  template: `
    <ActionBar title="My App"></ActionBar>
    <StackLayout orientation="vertical">
            <Label [text]="message" (tap)="onTap()"></Label>
    </StackLayout>
  `
})
export class AppComponent {
    public message: string = "Hello, Angular";
    public onTap() {
        this.message = "Text Changed";
        var test = new com.tns.TestObject();
        console.log(test.doSomething());
    }
}

edit: for future readers, the above code is in fact working now

I know you can do it with just normal Android classes, but havent been able to do it with my own custom classes, maybe im just missing something though (something to do with imports maybe?).

I am getting this error when trying to run the program

app/app.component.ts(21,24): error TS2304: Cannot find name 'com'.

and I have my object just under the main folder in my project

screenshot

Basically they want us to convert certain sections of the android app to nativescript at a time while leaving all the old native functionality in tact, so that eventually the whole project will be converted to nativescript, and thus one code base for both ios and android theoretically. Sounds like a really bad way to go about it, should just start from scratch imo.

TL;DR

How to use custom java class in nativescript code?

----- Additions from comments ------

An uncaught Exception occurred on "main" thread. com.tns.NativeScriptException: Calling js method onTouch failed

[object Object] File: "file:///data/data/org.nativescript.HelloWorld/files/app/tns_modules/tns-core-modules/ui/gestures/gestures.js, line: 97, column: 40

StackTrace: Frame: function:'GesturesObserver.androidOnTouchEvent', file:'file:///data/data/org.nativescript.HelloWorld/files/app/tns_modules/tns-core-modules/ui/gestures/gestures.js', line: 97, column: 41 Frame: function:'onTouch', file:'file:///data/data/org.nativescript.HelloWorld/files/app/tns_modules/tns-core-modules/ui/core/view.js', line: 113, column: 37

at com.tns.Runtime.callJSMethodNative(Native Method)
at com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1197)
at com.tns.Runtime.callJSMethodImpl(Runtime.java:1061)
at com.tns.Runtime.callJSMethod(Runtime.java:1047)
at com.tns.Runtime.callJSMethod(Runtime.java:1028)
...
11
  • If you bring the custom files into the project what you have here var test = new com.tns.TestObject() should indeed work. Does the log(test) actually output anything? As for your angular portion, is any of this going to be used on a web version? If not, I'd skip the angular piece and use plain NativeScript. There are pros/cons both ways for sure but if it's never going to be on the web, you don't gain anything with having angular in your nativescript app. Nothing that would sway me anyway :) Commented Feb 3, 2017 at 4:08
  • @BradMartin Ive updated my question with some more info, im also editing my .ts file that is the main native script project folder as well, not under platforms/android/ etc FYI. Not going to be using any web component with the code, so thanks for your suggestion Commented Feb 3, 2017 at 4:19
  • 2
    That's a TS error, nothing to do with nativescript at that point. So you have a couple options in handling the TS compiler. Set noEmitOnError:false in tsconfig.json for the project. This will allow the compiler to emit even with errors. Or you can put above the export, declare var com: any so TS knows com is just the type any There are more options in handling but that should help. TS errors are prefixed with TS so, TS2304 indicates a TS warning/error. No major road block with that :) Commented Feb 3, 2017 at 4:19
  • The NativeScript team also has android and iOS typescript typings to help with intellisense and informing TS of the native classes,methods,props, etc. so the compiler doesn't bark so much. You can add those with npm install tns-platform-declarations I think. They have another tool that attempts to generate TS typings for custom java/android libraries/modules added to your project. I haven't used it though. Commented Feb 3, 2017 at 4:23
  • 1
    Ok i did as you suggested by going noEmitOnError:false and declare var com: any which let it compile, but im getting a crash now, and the exception error isnt very useful, just saying to crashing in the onTouch in file gestures.js, which im assuming is related to on onTap() method ive got and crashing in there. Im going away from my computer for a bit, so ill only be able to reply in a while, but if you have any other suggestions please do leave them here, thanks a lot for this info. Commented Feb 3, 2017 at 4:36

2 Answers 2

2

Try exclude those round brackets :) Same thing to assigning classes i am using at plugin.

EDIT

It should be with those brackets :D

var test = new com.tns.TestObject();
console.log(test.doSomething());
Sign up to request clarification or add additional context in comments.

9 Comments

Hmm strange, i got it to work, but it wasnt because of the round brackets, i dont actually know what did the trick because it doesnt seem like I've changed anything important, but you are sort of correct, it doesnt actually need the round brackets, but it still works with them...
Yeah, after checking whole code i was like ehm what ? And about those not needed prefixed, var ArrayList = java.util.ArrayList; and then only need to call is var list=new ArrayList();
ah awesome, would there be a way to sort of globally define things like that in the project, or have to do it on a per file basis?
Probably you can one file eand export each these prefix variables and import them when needed
can we at least declare it in the file scope somehow? ive tried going declare var TestObject: com.tns.TestObject but that doesnt work, cant find "com" again, although the com was declared above it with declare var com: any
|
1

So as @Brad Martin explained in the comments, all you need is to declare what com is and you will be able to use the java file in your nativescript code without any hassle

//Java
package com.tns;

public class TestObject {
    public String doSomething () {
        return "hello";
    }
}

//Nativescript
import { Component } from "@angular/core";

declare var com: any //this is the important part

@Component({
  selector: "my-app",
  template: `
    <ActionBar title="My App"></ActionBar>
    <StackLayout orientation="vertical">
            <Label [text]="message" (tap)="onTap()"></Label>
    </StackLayout>
  `
})
export class AppComponent {
    public message: string = "Hello, Angular";
    public onTap() {
        this.message = "Text Changed";
        var test = new com.tns.TestObject(); //cant use this without the declare above
        console.log(test.doSomething()); //will print "hello" in the console
    }
}

Where my java file is located in the android project:

File location in Android project for reference

4 Comments

Somehow I am getting "it is not a function" error after I update the java file. So combined copied the file automatically to the platforms seems solved this issue. From here : github.com/NativeScript/nativescript-cli/issues/1577
Hello Fonix, I try your post in my app, and show this error: JS: ERROR TypeError: com.tns.TestObject is not a constructor and JS: ERROR ONTEXT {JS: "view": {JS: "def": {JS: "nodeFlags": 34262017,JS: "rootNodeFlags": 3554433,JS: "nodeMatchedQueries": 0,JS: "flags": 0,JS: "nodes": [JS: {JS: "nodeIndex": 0,JS: "parent": null, JS: "renderParent": null, JS: "bindingIndex": 0,JS: "outputIndex": 0,JS: "checkIndex": 0,JS: "flags": 33554433,JS: "childFlags": 49152,JS: "directChildFlags": 49152,JS: "childMatchedQueries": 0,JS: matchedQueries": {},JS: ...
@Fonix can you help me please?
@Aulonna I dont know what that error could be unfortunately, havnt touched angular in a long time

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.