【问题标题】:How to use custom native java classes / functions in nativescript?如何在 nativescript 中使用自定义的原生 java 类/函数?
【发布时间】:2017-06-20 08:34:20
【问题描述】:

所以我的经理似乎认为将一个应用从 2 个完全原生的 iOS 和 Android 应用转换为一个跨平台的 angular/nativecript 应用是一项简单的任务(对我来说这听起来是个糟糕的主意)。我试图研究这样做所需的努力。我创建了一个 helloworld nativescript 应用程序,我试图了解将现有本机代码集成到 nativescript 应用程序的最佳方法是什么(基本上我想访问我的本机 Web 服务功能)。我在这方面的知识非常有限。

我已经看到有一种可以使用make your own native packages 的方法,但这似乎需要付出很多努力和麻烦/麻烦。有没有办法只访问 nativescript 中的自定义本机 java 对象?例如:

//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());
    }
}

编辑:对于未来的读者,上面的代码实际上现在可以工作了

我知道你 can do it 只使用了普通的 Android 类,但我无法使用我自己的自定义类来做到这一点,也许我只是遗漏了一些东西(可能与导入有关?)。

我在尝试运行程序时遇到此错误

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

我的对象就在我项目的主文件夹下

基本上,他们希望我们一次将 android 应用程序的某些部分转换为 nativescript,同时保留所有旧的本地功能,以便最终将整个项目转换为 nativescript,从而为两个 ios 提供一个代码库和android理论上。听起来是一个非常糟糕的方法,应该从头开始 imo。

TL;DR

如何在nativescript代码中使用自定义java类?

----- 来自 cmets 的添加 ------

“主”线程上发生未捕获的异常。 com.tns.NativeScriptException: 调用js方法onTouch失败

[对象对象]文件: “file:///data/data/org.nativescript.HelloWorld/files/app/tns_modules/tns-core-modules/ui/gestures/gestures.js, 行:97,列:40

堆栈跟踪: 框架:函数:'GesturesObserver.androidOnTouchEvent',文件:'file:///data/data/org.nativescript.HelloWorld/files/app/tns_modules/tns-core-modules/ui/gestures/gestures.js', 行:97,列:41 框架:函数:'onTouch',文件:'file:///data/data/org.nativescript.HelloWorld/files/app/tns_modules/tns-core-modules/ui/core/view.js', 行:113,列: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)
...

【问题讨论】:

  • 如果您将自定义文件带入项目中,那么您在此处所拥有的 var test = new com.tns.TestObject() 应该确实可以工作。 log(test) 真的输出什么吗?至于你的角度部分,这是否将用于网络版本?如果没有,我会跳过角度部分并使用普通的 NativeScript。肯定有两种方式的优点/缺点,但如果它永远不会出现在网络上,那么在你的 nativescript 应用程序中使用 angular 将不会获得任何好处。无论如何,没有什么能动摇我:)
  • @BradMartin Ive 用更多信息更新了我的问题,我还在编辑我的 .ts 文件,该文件也是主要的本机脚本项目文件夹,而不是在 platform/android/ 等仅供参考。不会在代码中使用任何 Web 组件,所以感谢您的建议
  • 这是一个 TS 错误,此时与 nativescript 无关。因此,您在处理 TS 编译器时有几个选择。在项目的 tsconfig.json 中设置noEmitOnError:false。这将允许编译器即使有错误也能发出。或者您可以将declare var com: any 放在导出上方,这样TS 就知道com 只是any 的类型。处理中有更多选项,但这应该会有所帮助。 TS 错误以 TS 为前缀,因此 TS2304 表示 TS 警告/错误。没有重大障碍:)
  • NativeScript 团队也有 android 和 iOS typescript 类型来帮助智能感知和通知 TS 原生类、方法、props 等,这样编译器就不会那么吵了。我想你可以用npm install tns-platform-declarations 添加那些。他们有另一个工具,它试图为添加到您的项目中的自定义 java/android 库/模块生成 TS 类型。不过我没用过。
  • 好吧,我按照你的建议去做了 noEmitOnError:falsedeclare var com: any 让它编译,但我现在崩溃了,异常错误不是很有用,只是说在 onTouch 中崩溃在文件gestures.js中,我假设它与我得到的onTap()方法有关并在那里崩溃。我暂时离开我的电脑,所以我只能在一段时间内回复,但如果您有任何其他建议,请在这里留下,非常感谢您提供的信息。

标签: android ios nativescript


【解决方案1】:

尝试排除那些圆括号 :) 与我在插件中使用的分配类相同。

编辑

它应该是那些括号 :D

var test = new com.tns.TestObject();
console.log(test.doSomething());

【讨论】:

  • 嗯,很奇怪,我让它工作了,但这不是因为圆括号,我实际上不知道有什么诀窍,因为看起来我没有改变任何重要的东西,但你是排序正确的,它实际上不需要圆括号,但它仍然适用于它们......
  • 是的,在检查了整个代码之后,我就像ehm what ? 而那些不需要前缀的,var ArrayList = java.util.ArrayList; 然后只需要调用是var list=new ArrayList();
  • 太棒了,有没有办法在项目中全局定义类似的东西,或者必须在每个文件的基础上做?
  • 也许你可以一个文件并导出每个这些前缀变量并在需要时导入它们
  • 我们至少可以在文件范围内声明它吗?我试过去declare var TestObject: com.tns.TestObject,但这不起作用,无法再次找到“com”,尽管 com 在其上方声明为declare var com: any
【解决方案2】:

正如@Brad Martin 在 cmets 中解释的那样,您只需声明 com 是什么,您就可以在您的 nativescript 代码中使用 java 文件,而无需任何麻烦

//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
    }
}

我的java文件在android项目中的位置:

【讨论】:

  • 在更新 java 文件后不知何故出现“它不是函数”错误。所以结合自动将文件复制到平台似乎解决了这个问题。从这里:github.com/NativeScript/nativescript-cli/issues/1577
  • 您好 Fonix,我在我的应用程序中尝试您的帖子,并显示此错误:JS: ERROR TypeError: com.tns.TestObject is not a constructorJS: 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 你能帮帮我吗?
  • @Aulonna 不幸的是,我不知道那个错误可能是什么,很长时间没有接触到角度
猜你喜欢
  • 1970-01-01
  • 2018-06-28
  • 1970-01-01
  • 2017-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多