首页 > 编程知识 正文

native代码如何调js,native怎么说

时间:2023-12-28 11:56:49 阅读:327843 作者:STKZ

本文目录一览:

hybrid App中js调用native接口原理

移动网络的发展推动移动APP盛行,目前市场上APP开发技术的类型主要有三种,native开发、hybrid开发、RN/weex开发。

本文主要讲述hybrid APP中js调用native原理。hybrid APP就是利用Android/iOS上webview加载web网页,其实就是相当于用native做了一个外壳,然后里面加载网页。那站在业务层面上,只要没有太依赖性能,都能满足需求,那这里面有可能会用到一些硬件功能,比如:相机、位置等,这时就必须调用native。

1.js 调用 native,Android里面主要通过WebViewClient.shouldOverrideUrlLoading方法拦截指定格式的URL,通过拦截特定URL和获取对应的参数,来调用native对应的功能。这里我们主要通过cordova插件,来做例子说明

上面我们看到cordova的初始化,这里面主要对回调callback进行定义,js调用native之后,native处理完结果,将结果返回js,就是通过callback完成。

3.构造链接,并发送链接pokeNative

这里我们看到调用native可以通过iframe和通过XHR完成。

这就是js调用native的方式,native完成处理之后,通过webView.addJavascriptInterface调用js中挂载在window对象的方法,这是一个统一的回调nativeCallback ,通过callbackID识别出本次结果需要回调js中的哪个function。然后本次交互就全部完成了

总结一下,主要同理是通过native两个方法:addJavascriptInterface和shouldOverrideUrlLoading完成js和native交互。

怎么在web worker启动的js线程调用native.js

HTML5-Web Workers实现多线程:

当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成。虽然在JavaScript中有setInterval和setTimeout函数使javaScript看起来好像使多线程执行,单实际上JavaScript使单线程的,一次只能做一件事情。

可以运行以下示例,检验js的单线程特性。

相关代码请到github查看。

div id='container'/div

script

window.alert('hi');

setTimeout(function(){

var ul = document.createElement('ul');

var li = document.createElement('li');

var text = document.createTextNode('world');

var container = document.getElementById('container');

li.appendChild(text);

ul.appendChild(li);

container.appendChild(ul);

console.log('done!');

},2000);

/script123456789101112131415123456789101112131415

如果JavaScript是多线程,在弹出警告框两秒后,页面应该出现一个li标签(内容为world)。事实上因为JavaScript是单线程,所以如果你不点击弹出框的确定按钮,world这个li永远也出不来。

点击确定后

web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能。您可以继续做任何愿意做的事情:点击、选取内容等等,而此时 web worker 在后台运行。

我们需要把希望单独执行的javascript代码放到一个单独的js文件中,然后在页面中调用Worker构造函数来创建一个线程,参数是该文件路径,参数存放如果是相对地址,那么要以包含调用Worker构造函数语句所在脚本为参照,如果是绝对路径,需要保证同源(协议+主机+端口)。这个文件不需要我们在页面使用script标签显示引用。

var worker = new Worker('src/js/worker.js');11

我们可以看到worker对象只有两个属性,其实是两个回调函数句柄

onerror:当worker运行出现错误,并且没有在worker中ing捕获,会在此捕获

onmessage:当worker向主线程发送消息是调用

在其prototype内有两个重要方法

postMessage:很熟悉的赶脚,之前我们介绍过window对象的postMessage()方法,woker的postMessage方法和window的比较类似,但参数略有不同,只需要传递消息内容就可以,而且支持所有JavaScript原生数据类型,当然不放心的话同样也可以序列化为字符串传递

terminate:终止worker执行,有些worker执行比较慢,主线程可以主动终止其执行

下面我们用web workers重写上面那个例子。

相关代码请到github查看。

test_web_worker.html

script

var worker = new Worker('./worker.js');

window.alert('hi');

/script12341234

worker.js

setTimeout(function(){console.log('done!');},2000);

在Android上怎样实现JAVA和JS交互

在Android的开发过程中、遇到一个新需求、那就是让Java代码和Javascript代码进行交互、在IOS中实现起来很麻烦、而在Android中相对来说容易、Android对这种交互进行很好的封装、其实可以很简单的用Java代码调用WebView中的js函数、也可以用WebView中的js来调用Android应用中的Java代码

一、网页的JS代码调用ANDROID中JAVA代码的方法

在网页中调用java代码、需要在webview控件中添加javascriptInterface

contentWebView = (WebView) findViewById(R.id.webview);

//启用javascript

contentWebView.getSettings().setJavaScriptEnabled(true);

contentWebView.addJavascriptInterface(this, "js对象名");

在Activity中定义一个要被js调用的方法、src为js传递过来的参数、如果没有不传也可以的。

public void jsFunction(final String str) {

Toast.makeText(this, str, Toast.LENGTH_SHORT).show();

runOnUiThread(new Runnable() {

@Override

public void run() {

//在里对Android应用的UI进行处理

}

});

}

在网页中、只需要像调用js方法一样、进行调用就可以

a onClick="window.js对象名.jsFunction(´hello world´)"

点击调用java代码并传递参数

/a

二、ANDROID中JAVA代码调用网页的JS代码的方法

Java代码调用js并传参其实是通过WebView的loadUrl方法去调用的、只是参数url的写法不一样

// 无参数调用

contentWebView.loadUrl("javascript:javacalljs()");

// 传递参数调用

contentWebView.loadUrl("javascript:javacalljswithargs("

+ "´hello world´" + ")");

三、JAVA和JS交互注意事项

1、Java 调用 js 里面的函数、效率并不是很高、估计要200ms左右吧、做交互性很强的事情、这种速度很难让人接受、而js去调Java的方法、速度很快、50ms左右、所以尽量用js调用Java方法

2、Java 调用 js 的函数、没有返回值、调用就控制不到

3、Js 调用 Java 的方法、返回值如果是字符串、你会发现这个字符串是 native 的、转成 locale 的才能正常使用、使用 toLocaleString() 函数就可以、不过这个函数的速度并不快、转化的字符串如果很多、将会很耗费时间

4、网页中尽量不要使用jQuery、执行起来需要5-6秒、最好使用原生的js写业务脚本、以提升加载速度、改善用户体验

react-native: ios原生调用js方法

ReactEventEmit.h

#import React/RCTEventEmitter.h

#import React/RCTBridgeModule.h

@interface ReactEventEmit : RCTEventEmitterRCTBridgeModule

-(void)goToCashier:(NSString*) result;

@end

ReactEventEmit.m

#import "ReactEventEmit.h"

@implementation ReactEventEmit

@synthesize bridge = _bridge;

RCT_EXPORT_MODULE(ReactEventEmit);

+ (id)allocWithZone:(NSZone*)zone {

    staticReactEventEmit*sharedInstance =nil;

    staticdispatch_once_tonceToken;

    dispatch_once(onceToken, ^{

        sharedInstance = [superallocWithZone:zone];

    });

    returnsharedInstance;

}

-(NSArray *)supportedEvents{

    return @[@"goToCashier"];

}

-(void)goToCashier:(NSString*) result

{

    NSLog(@"======== cashierSuccess ========== %@",result);

    [self sendEventWithName:@"goToCashier" body:@{@"result": result}];

}

@end

RN的module初始化是由RN内部实现的,所以我们调用这个实例的时候,必须是这样子:

ReactEventEmit *emit = [ReactEventEmit allocWithZone:nil];

 [emit goToCashier:@"fail"];

JS端调用:

const ReactEventEmit = NativeModules.ReactEventEmit;

const myReactEventEmit = new NativeEventEmitter(ReactEventEmit);

this.listener = myReactEventEmit.addListener('goToCashier', (data: { result: string }) = {

        console.warn('====== cashierSuccess ======= ' + JSON.stringify(data));

        this.process(data.result);

      });

native与JS简单交互

使用 UIWebView 的 - (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script; 方法,就可以调用JS的方法了.

点击网页上的某个按钮,想要执行native的某个方法.

比如,网页上有一个分享按钮,点击后弹出分享平台选择view,但这个view及弹出动画都是native这边实现的.所以此时JS需要调用native方法,并将分享内容参数传给native.

思路:给JS中的元素桥接一个native的对象或函数.这样点击网页上的分享按钮时,就可以执行native的方法了.

上面的思路如何实现呢?

系统已经为我们提供了相关API,那就是OC的JSContext类的类别SubscriptSupport提供的方法

- (void)setObject:(id)object forKeyedSubscript:(NSObject NSCopying *)key;

Use this method (or Objective-C subscript syntax) to bridge native objects or functions for use in JavaScript.

object参数通常是一个block对象.上述方法也可以使用下标语法: context[@"xxx"] = ^{};

当webView加载完成后,在该代理方法里实现.

这样当用户点击js上的分享按钮时,就可以弹出本地的分享选择视图了.

由于不太懂HTML5和JavaScript,所以上面有些地方的表述可能并不恰当.

js调用Native

JS 调用prompt方法,Android收到回调onJSPrompt 将native bridges方法注册给js.window,然后js就可以调用iframe.scr 打开scheme,native端就可以在shouldOverrideUrlLoading()对scheme进行拦截解析处理

2.解析uri,从namespaceMap中根据module获取最终AbstractBridgeModule的实现类

3.通过方法注解

shouldOverrideUrlLoading调用时机:二级链接

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。