如何把React Native嵌入到原生android原生应用应用中

内容字号:
段落设置:
字体设置:
教你ReactNative撸android原生百度定位SDK服务(跨平台模块自定
哈喽,最近一直在研究reactNative没有碰原生的东西已经很久了.不知道大家是否想过一个问题呢?reactNative开发中用到的语言是Js.但是我们如果想做百度定位或者微博分享等第三方sdk的集成时,会不会碰到以下问题.
第三方sdk是否有reactNative的sdk.
reactNative是否支持调用原生sdk
第三方sdk是否有reactNative的sdk.
暂不支持,很抱歉,由于reactNative技术太新,而且更新较快.目前暂未发现第三sdk有做这块的.
既然他们还没来得及做,是否又有民间艺人做了这事?没错确实有.如果你在github上去搜索确实能找到一些.不过有的时候我们会发现一个问题.他们的项目可能断更了.也就是说sdk更新后,作者并未能及时更新.导致你集成进来后压根就不能用.
reactNative是否支持调用原生sdk
支持,是的官方说了他们支持的.下面请看原话.
你需要一个翻译吗下面就是哦:
有时候App需要访问平台API,但React Native可能还没有相应的模块包装;或者你需要复用一些Java代码,而不是用Javascript重新实现一遍;又或者你需要实现某些高性能的、多线程的代码,譬如图片处理、数据库、或者各种高级扩展等等。
我们把React Native设计为可以在其基础上编写真正的原生代码,并且可以访问平台所有的能力。这是一个相对高级的特性,我们并不认为它应当在日常开发的过程中经常出现,但具备这样的能力是很重要的。如果React Native还不支持某个你需要的原生特性,你应当可以自己实现该特性的封装。
没有错,官方都说了,它支持的.那还怕个J*,那么我们现在就撸起袖子干他丫的.搞起.
集成百度定位
这是温柔的一条提示:题纲带星号的是你应该关注的重点
初始化项目
申请认证成为百度开发者
下载基础开发包并导入android Studio
编写Native模块*
reactNative调用Native模块*
初始化项目
我们打开命令行,输入 react-native init [你的项目名称] 不含括弧,如下图所示
然后你就会看到下面这个样子的. 一切顺利的话只等他结束.
为了验证项目是否正常init,现在你可以使用react-native run-android 运行你的应用.在这之前你要确保adb是否都已经链接好哦.
申请认证成为百度开发者
&打开它,然后注册一个账号.简单的认证后找到&&,然后你会看到如下界面.
那么我们首先来创建一个应用吧.点击创建应用.
注意以下几点:
应用类型选择android sdk
SHA1可以参考官方的方法生成.&
包名不要填错了 包名需要在文件build.gradle中查询 applicationId,并确保 applicationId 与在 AndroidManifest.xml 中定义的包名一致
随后你会获得一个叫ak的key.这个key后面要配置到你的AndroidManifest.xml .后面会讲解到.
你可以点击应用列表中的设置,看到你自己应用的ak
下载基础开发包并导入android Studio
我想你正常开发reactnative的时候可能用的是atom编辑器或者webStorm之类的,但是因为我们的sdk基础包是native的,所以如果你写java的时候用那些不支持提示或自动导java包的ide会很蛋疼的.所以在此请你先确保要安装好哦.
我们先在官方找到自定义下载包地址.&&也就是这个链接了.勾选你需要的服务.这里我只选了基础定位.然后点击开发包下载.
下载后的解压包里有一个叫libs的文件夹.
现在我们打开androidStudio,找到这个选项.
找到你的项目路径,打开项目下的android目录.
注意是打开android目录.
注意是打开android目录.
注意是打开android目录.
重要的事情说三遍.
运行起来后,将项目切换成Project模式.(默认是android模式)
将刚刚下载的压缩文件中的libs复制到项目中的App文件夹下.
Paste_Image.png
打开APP文件夹下的build.Gradle,在加入如下代码.
.... 这是其他的代码,你别动它.这一行不需要,不要复制进来了.
sourceSets {
jniLibs.srcDirs = ['libs']
打开AndroidManifest文件,在application标签中添加服务和ak秘钥.
android:name=&com.baidu.location.f&
android:enabled=&true&
android:process=&:remote&&&
android:name=&com.baidu.lbsapi.API_KEY&
android:value=&GN1lCG*************4I&&s& /&
android:name=&android.permission.INTERNET& /&
android:name=&android.permission.SYSTEM_ALERT_WINDOW&/&
android:name=&android.permission.ACCESS_COARSE_LOCATION&&&
android:name=&android.permission.ACCESS_FINE_LOCATION&&&
android:name=&android.permission.ACCESS_WIFI_STATE&&&
android:name=&android.permission.ACCESS_NETWORK_STATE&&&
android:name=&android.permission.CHANGE_WIFI_STATE&&&
android:name=&android.permission.READ_PHONE_STATE&&&
android:name=&android.permission.WRITE_EXTERNAL_STORAGE&&&
android:name=&android.permission.MOUNT_UNMOUNT_FILESYSTEMS&&&
至此恭喜你已经完成一个基础的定位环境了.
编写Native模块*
编写一个Native模块分为三步
1.建一个中间访问对象,
2.建一个ReactPackage对象.
3.将ReactPackage对象加载到MainApplication中.
接下来我们就来一步一步做.
新建一个BaiduLBS类继承ReactContextBaseJavaModule. 声明一个startLocation()的方法.供给RN调用,参数Callback是用于回调js的对象.我们再定位成功后要调用它.注意方法的上面必须加上 @ReactMethod注解.具体的调用定位请参考代码吧.然后重写GetName方法.return的值就是rn中调用的组件.
package com.
import android.util.L
import com.baidu.location.BDL
import com.baidu.location.BDLocationL
import com.baidu.location.LocationC
import com.baidu.location.LocationClientO
import com.baidu.location.P
import com.facebook.react.bridge.C
import com.facebook.react.bridge.ReactApplicationC
import com.facebook.react.bridge.ReactContextBaseJavaM
import com.facebook.react.bridge.ReactM
import java.util.L
public class BaiduLBS
extends ReactContextBaseJavaModule {
public LocationClient mLocationClient = null;
private Callback locationC
public BaiduLBS(ReactApplicationContext reactContext) {
super(reactContext);
@ReactMethod
public void startLocation( Callback locationCallback) {
this.locationCallback = locationC
mLocationClient = new LocationClient(getReactApplicationContext());
mLocationClient.registerLocationListener(myListener);
LocationClientOption option = new LocationClientOption();
option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy
option.setCoorType(&bd09ll&);
int span = 0;
option.setScanSpan(span);
option.setIsNeedAddress(true);
option.setOpenGps(true);
option.setLocationNotify(true);
option.setIsNeedLocationDescribe(true);
option.setIsNeedLocationPoiList(true);
option.setIgnoreKillProcess(false);
option.SetIgnoreCacheException(false);
option.setEnableSimulateGps(false);
mLocationClient.setLocOption(option);
mLocationClient.start();
Log.e(&tag&,&ok&);
public BDLocationListener myListener = new BDLocationListener() {
public void onReceiveLocation(final BDLocation bdLocation) {
Log.e(&TGA&, &回掉+1&);
final StringBuffer sb = new StringBuffer(256);
sb.append(&time : &);
sb.append(bdLocation.getTime());
sb.append(&\nerror code : &);
sb.append(bdLocation.getLocType());
sb.append(&\nlatitude : &);
sb.append(bdLocation.getLatitude());
sb.append(&\nlontitude : &);
sb.append(bdLocation.getLongitude());
sb.append(&\nradius : &);
sb.append(bdLocation.getRadius());
if (bdLocation.getLocType() == BDLocation.TypeGpsLocation) {
sb.append(&\nspeed : &);
sb.append(bdLocation.getSpeed());
sb.append(&\nsatellite : &);
sb.append(bdLocation.getSatelliteNumber());
sb.append(&\nheight : &);
sb.append(bdLocation.getAltitude());
sb.append(&\ndirection : &);
sb.append(bdLocation.getDirection());
sb.append(&\naddr : &);
sb.append(bdLocation.getAddrStr());
sb.append(&\ndescribe : &);
sb.append(&gps定位成功&);
} else if (bdLocation.getLocType() == BDLocation.TypeNetWorkLocation) {
sb.append(&\naddr : &);
sb.append(bdLocation.getAddrStr());
sb.append(&\noperationers : &);
sb.append(bdLocation.getOperators());
sb.append(&\ndescribe : &);
sb.append(&网络定位成功&);
} else if (bdLocation.getLocType() == BDLocation.TypeOffLineLocation) {
sb.append(&\ndescribe : &);
sb.append(&离线定位成功,离线定位结果也是有效的&);
} else if (bdLocation.getLocType() == BDLocation.TypeServerError) {
sb.append(&\ndescribe : &);
sb.append(&服务端网络定位失败,可以反馈IMEI号和大体定位时间到loc-,会有人追查原因&);
} else if (bdLocation.getLocType() == BDLocation.TypeNetWorkException) {
sb.append(&\ndescribe : &);
sb.append(&网络不同导致定位失败,请检查网络是否通畅&);
} else if (bdLocation.getLocType() == BDLocation.TypeCriteriaException) {
sb.append(&\ndescribe : &);
sb.append(&无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机&);
sb.append(&\nlocationdescribe : &);
sb.append(bdLocation.getLocationDescribe());
List&Poi& list = bdLocation.getPoiList();
if (list != null) {
sb.append(&\npoilist size = : &);
sb.append(list.size());
for (Poi p : list) {
sb.append(&\npoi= : &);
sb.append(p.getId() + & & + p.getName() + & & + p.getRank());
locationCallback.invoke(sb.toString());
public String getName() {
return &MyLBS&;
新建一个AnExampleReactPackage类实现ReactPackage接口.并在createNativeModules方法中加载BaiduLBS类.
package com.
import com.facebook.react.ReactP
import com.facebook.react.bridge.JavaScriptM
import com.facebook.react.bridge.NativeM
import com.facebook.react.bridge.ReactApplicationC
import com.facebook.react.uimanager.ViewM
import java.util.ArrayL
import java.util.C
import java.util.List;
class AnExampleReactPackage implements ReactPackage {
public List&Class&? extends JavaScriptModule&& createJSModules() {
return Collections.emptyList();
public List&ViewManager& createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
public List&NativeModule& createNativeModules(
ReactApplicationContext reactContext) {
List&NativeModule& modules = new ArrayList&&();
modules.add(new BaiduLBS(reactContext));
在MainApplication中的getPackages方法中添加AnExampleReactPackage.代码如下
package com.
import android.app.A
import com.facebook.react.ReactA
import com.facebook.react.ReactNativeH
import com.facebook.react.ReactP
import com.facebook.react.shell.MainReactP
import com.facebook.soloader.SoL
import java.util.A
import java.util.L
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
protected boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
protected List&ReactPackage& getPackages() {
return Arrays.&ReactPackage&asList(
new MainReactPackage(),
new AnExampleReactPackage()
public ReactNativeHost getReactNativeHost() {
return mReactNativeH
public void onCreate() {
super.onCreate();
SoLoader.init(this,
让我们喘一会气歇一下,理一下思路吧.
至此你已经编写完成所有的native模块.简单来说当MainApplication 实现了ReactApplication 接口以后就会通过getPackages来加载你自定义的模块和原生reactNative的模块.其中MainReactPackage就是原生的模块.那么我们自定位的AnExampleReactPackage中就加载了我们自定义的百度定位sdk.然后rn中才能调用到.
reactNative调用Native模块*
保存你的代码,现在可以关掉AS了.打开你写JS的IDE吧.让我们愉快的调用刚刚自定义的sdk接口.
打开你rn的目录,新建一个BaiduLbs.js文件.然后使用NativeModules对象将刚刚原生中定位的模块加载进来.注意其中 NativeModules.MyLBS中的MyLBS就是我们写原生中BaiduLBS 类的getName的返回值.
'use strict';
import { NativeModules } from 'react-native';
export default NativeModules.MyLBS;
找到index.android.js 文件.import刚刚我们声明的模块. 代码如下:
import React, {Component} from 'react';
AppRegistry,
StyleSheet,
} from 'react-native';
import MyLBS from './BaiduLbs'
export default class BaiduMapNR extends Component {
constructor(props) {
super(props);
this.state = {
location: null,
componentDidMount() {
MyLBS.startLocation((location)=& {
this.setState({location: location})
render() {
if (this.state.location) {
{ this.state.location}
AppRegistry.registerComponent('BaiduMapNR', () =& BaiduMapNR);
在你项目的目录下打开命令行.输入
react-native run-android .
下面就是见证奇迹的时刻啦.有木有小激动呢?
ok.成功出现我们定位的地址啦.哈哈 是不是很简单.相信你又学会了一招.(⊙v⊙)嗯,加油哦.相信这么爱学习的你,肯定是整天沉迷在其中.那么下面的官方教程你也要抽时间学习哦.
分享给小伙伴们:
本类最热新闻
48小时最热
01020304050607089101112
CopyRight © 2015- , All Rights Reserved.&nbsp&#8250&nbsp&nbsp&#8250&nbsp
React Native是原生开发的末日吗?
原文: &人们把React Native看作是一次编写随处运行的一个解决方案,理论上可以加快那些需要同时为iOS和Android平台编写的app的开发速度,同时让web开发者也能轻松编写本地应用,但是 React Native是你下个项目的最佳选择吗?&是当前流行的同名web库React的原生版本,它的主要目的是把React的强大带到本地开发中。React Native控件是纯粹,无副作用的函数,能在任意时刻返回视图的效果。因此更容易写出状态无关的视图,因为你不需要在状态改变的时候关注视图的更新,framework已经为你做了这件事情。UI的渲染实际使用的是本地视图,所以最终的用户体验并不会像那些只是在WebView里渲染web控件的解决方案那样糟糕。评价一项新技术的最佳方法是使用它。我们召集了一个4个iOS和Android原生开发者的团队去策划与研究React Native。这里是我们的行动计划:创建一个运行在 iOS和Android双平台上的推特客户端。衡量代码的可复用性评估最终app的外观和感受研究第三方库的成熟度采访当前的 react native开发者阅读官方文档查看核心功能的源码我们创建的推特iOS和安卓客户端的源码在Spikes里面。repo:关于如何配置测试环境的文档相当贫乏,而且基本是过时的。结果我们花了4天的时间才成功运行了所有的测试。虽然我们之前的确没有跑JavaScript测试的经验,但是我们还是发现设置测试环境所付出的努力过于夸张。也有一些其它的技巧,但是多数都会导致兼容问题。推荐使用的IDE是,以及在其之上的插件,Nuclide添加了对 React Native开发和静态分析工具的支持。对于普通的JavaScript开发来说,也许这是一个好的编辑器,但是我们发现它跟我们习惯了的IDE如 Xcode 和 Android Studio比起来还是落后了很多。比如,对于最基本的refactor它都不支持,这可能会降低开发速度。作为原生开发者,我们发现React Native的学习曲线非常陡峭,要适应此框架上的开发,可能得花上一个月的时间。对于已经熟悉JavaScript开发,, flow layout以及甚至于React的人来说,上手 React Native要快得多。有些特定的功能无法仅仅通过JavaScript实现,需要原生代码:推送通知deep linking需要暴露给React的原生UI控件大约有80%的代码都是用JavaScript写的,可以在iOS和Android上通用。Hot Reloading在概念上类似于Android上的&。每当保存一个源码文件的时候,运行app的设备立即部署这些变化,因此加快了反馈。虽然它工作起来好于 Instant Run,但是仍然时不时的出现问题,需要重启app。我们不能否认很多时候我们需要解决一个别人在我们之前已经解决的问题,所以我们决定使用第三方库,避免重复造轮子。虽然在iOS和Android上有许多库可以选择,但是我们不敢对React Native说同样的话。当然肯定有相当数量的库,但是就跟我们预料的一样,他们中的一部分不能总是按照我们的预期工作。另一个值得一提的事情就是React Native的。虽然带来更多特性,让框架日趋成熟是好事,但是他们同时也带来了巨大的变化,也许这正是Facebook“快速行动,破除陈规”的文化使然。这些改变有时对于开发者来说是一个负担,因为在框架更新的时候我们需要花许多时间来修复。但是我们也不能否认这是预料之中的,因为框架还未到稳定状态,仍在开发之中。虽然目前具有这些优缺点:工具的状态,文档的缺乏以及第三方库的不稳定,但是我们感觉相对于传统的原生开发,使用React Native确实能节省一些时间。根据我们采访过的开发者所述,在真实项目中,可以节省大约30%的开发时间。当然这只是比较高的一种估计,取决于各种因素,就如前面我们提到的,最关键的就是团队中有人具有web开发方面的知识。此时你可能觉得React Native只是另一个“一次编写,到处运行”的 框架,比如&&或者&,但是你可能错了。就如Facebook在他们博客中明确声明的那样,他们阐述了和其它平台之间的不同,他们的目的是引进web上已经很成功的React模式到原生开发中,同时不管在什么平台都由一班人马开发。他们把这种方式称为“learn once, write everywhere”。React Native的工作原理是把JavaScript文件嵌入到app中,并在本地运行它。你还可以把这些文件放在远程服务器上,在app联网的时候获取它们的最新版本。这可以让应用的更新非常快,无需在应用商店检查版本。也有一些第三方的库提供这样的解决方案,使用它们意味着对于数据不多的较小应用(比如节日app),后台可以不需要了。绝大多数代码都是基于JavaScript和React的模式。因此典型的React Native应用团队应该是由JavaScript工程师组成的,因为理论上他们已经熟悉了此框架使用的工具和开发方式:React, EcmaScript, Redux 以及 Flex layout。开始在一个像React Native这样的新平台上工作,我们所做的第一件事就是探索当前的文档,包括官方的和社区的。我们发现虽然Facebook努力保持更新,但当前的版本还是有相当一部分控件的文档匮乏。而这点在互联网上的文档中体现得就更明显了,因为几个新版本之后,这些文档通常都已经过时了。当文档不能满足我们的时候我们尝试去看React Native的源码,但是我们对代码库的质量感到失望。可能是因为急于给框架增加新功能的原因,他们有时也许忽略了代码的简洁性。说到核心的React Native library,我们发现许多主要的控件都是处于Work-In-Progress&状态。在不同的版本之间,官方文档关于如何实现一些关键功能(如navigation)上不断的改变自己所推荐的控件。而要从一个控件迁移到另一个并不简单,需要做不少的工作。当然是可以使用第三方控件的,但是在数量上无法和iOS和安卓相比。一个很大的问题在于,这些控件无法保证和React Native的新版本兼容。当iOS和安卓的SDK更新之后, React Native要过一段时间才能把这些饿新的API整合到自己的核心库中。React Native团队为了让开发者能够使用最新的API更新很快,但是优先级取决于每个API的需求大小。可能会出现下个版本引入某些新特性,而某些功能却遥遥无期。我们发现 React Native的一个很好的使用场景是那些临时性的项目,比如音乐会或者会议的app。但是经过四个月的研究我们可以明确的说React Native还不是一个成熟稳定的平台。因此,我们认为React Native还没有准备好在长期的项目中被采用。这并不排除它可以用在其它类型的app上,以及团队中有级别较高的JavaScript专家的情况。React Native似乎更适合UI简单,动画不复杂,生命周期不长或者性能要求不高的app。我们创建的demo app完全开源:。关于更多的Novoda开源项目,请看。
你可以定义成你项目的logo图片,可以设置水波颜色、波长、波宽、字体大
下一篇: 原文地址: http://blog.csdn.net/mr_immortalz/article/details/ github 代码下载地址 : /ImmortalZ/StereoView 嗯,2个月没有写博客,是要好好反省下,趁着放暑假把这两个月看的东西好好沉淀下。嗯,就立下这个Flag,希望不要React Native 中的 Android 原生模块
我们要写一个什么东西
编写一个 React Native 的 Android 原生模块需要以下步骤:
创建一个 ReactPackage,把很多模块(Native 和 Javascript)包含在一起,然后在 MainActivity 中的 getPackages 方法引用。
创建一个 Java 类,继承 ReactContextBaseJavaModule 并实现需要的接口,然后注册到我们的 ReactPackage。
覆写上述类的 getName 方法,这个方法会作为 Javascript 的调用方法名。
使用 @ReactMethod 注解把需要的公共方法暴露给 Javascript。
最后,在 Javascript 中通过 NativeModules 导入你的模块。
创建一个 ReactPackage
package com.
import com.facebook.react.ReactA
import com.facebook.react.ReactP
import com.facebook.react.shell.MainReactP
import java.util.A
import java.util.L
public class MainActivity extends ReactActivity {
protected String getMainComponentName() {
return "MyApp";
protected boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
protected List getPackages() {
return Arrays.asList(
new MainReactPackage()
import com.myapp.imagepicker.*; // import the package
public class MainActivity extends ReactActivity {
protected List getPackages() {
return Arrays.asList(
new MainReactPackage(),
new ImagePickerPackage() // include it in getPackages
package com.myapp.
import com.facebook.react.ReactP
import com.facebook.react.bridge.JavaScriptM
import com.facebook.react.bridge.NativeM
import com.facebook.react.bridge.ReactApplicationC
import com.facebook.react.uimanager.ViewM
import java.util.ArrayL
import java.util.C
import java.util.L
public class ImagePickerPackage implements ReactPackage {
public List createNativeModules(ReactApplicationContext reactContext) {
List modules = new ArrayList&&();
modules.add(new ImagePickerModule(reactContext));
public List&Class&? extends JavaScriptModule&& createJSModules() {
return Collections.emptyList();
public List createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
创建一个 ReactContextBaseJavaModule
package com.myapp.
import com.facebook.react.bridge.ReactContextBaseJavaM
public class ImagePickerModule extends ReactContextBaseJavaModule {
public ImagePickerModule(ReactApplicationContext reactContext) {
super(reactContext);
public String getName() {
return "ImagePicker";
import com.facebook.react.bridge.C
import com.facebook.react.bridge.ReadableM
public class ImagePickerModule extends ReactContextBaseJavaModule {
@ReactMethod
public void openSelectDialog(ReadableMap config, Callback successCallback, Callback cancelCallback) {
Activity currentActivity = getCurrentActivity();
if (currentActivity == null) {
cancelCallback.invoke("Activity doesn't exist");
public class ImagePickerModule extends ReactContextBaseJavaModule {
private static final int PICK_IMAGE = 1;
private Callback pickerSuccessC
private Callback pickerCancelC
@ReactMethod
public void openSelectDialog(ReadableMap config, Callback successCallback, Callback cancelCallback) {
Activity currentActivity = getCurrentActivity();
if (currentActivity == null) {
cancelCallback.invoke("Activity doesn't exist");
pickerSuccessCallback = successC
pickerCancelCallback = cancelC
final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
final Intent chooserIntent = Intent.createChooser(galleryIntent, "Pick an image");
currentActivity.startActivityForResult(chooserIntent, PICK_IMAGE);
} catch (Exception e) {
cancelCallback.invoke(e);
public class ImagePickerModule extends ReactContextBaseJavaModule implements ActivityEventListener {
public ImagePickerModule(ReactApplicationContext reactContext) {
super(reactContext);
reactContext.addActivityEventListener(this);
public void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
if (pickerSuccessCallback != null) {
if (resultCode == Activity.RESULT_CANCELED) {
pickerCancelCallback.invoke("ImagePicker was cancelled");
} else if (resultCode == Activity.RESULT_OK) {
Uri uri = intent.getData();
if (uri == null) {
pickerCancelCallback.invoke("No image data found");
pickerSuccessCallback.invoke(uri);
} catch (Exception e) {
pickerCancelCallback.invoke("No image data found");
NativeModules.ImagePicker.openSelectDialog(
{}, // no config yet
(uri) =& { console.log(uri) },
(error) =& { console.log(error) }}

我要回帖

更多关于 android 嵌入浏览器 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信