此文是我的出版书籍《React Native 精解与实战》连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理、React Native 组件布局、组件与 API 的介绍与代码实战,以及 React Native 与 iOS、Android 平台的混合开发底层原理讲解与代码实战演示,精选了大量实例代码,方便读者快速学习。

书籍配套视频教程「80 节实战课精通 React Native 开发」:此视频课程建议配合书籍学习,书籍中原理性的东西讲解的比较清晰,而视频教程对于组件、API 等部分的代码实战开发讲解比较直观。

书籍所有相关资料请访问:http://rn.parryqiu.com

本章继续介绍 Android 平台下的混合开发原理以及实战,同时我们还可以深入理解React Native 与 Android 平台的通信机制。

12.1 Android 平台混合开发简介

与 iOS 平台的混合开发一样,有时我们遇到 React Native 框架没有提供的原生 Android 平台 API 时,我们就需要自己来进行 React Native 平台与 Android 平台的混合开发。

同样,混合开发还可以利用起来现有的 Android 原生平台的代码,并可以用于开发一些高性能、多线程的需求场景。

React Native 框架的设计同样为 Android 原生平台提供了混合开发的可能性,这部分依然属于 React Native 开发高阶的部分,在开发前需要掌握了 Android 原生平台的开发语言及开发流程,不过不了解的话也可以学习一下,了解 React Native 平台与 Android 平台的通信原理。

学习的方法我们还是在原理讲解的时候结合一个实际的小实例结合代码进行讲解,而不是仅仅空洞地讲解概念性的东西,便于大家理解。最后我们还将完成一个更加贴近实际的小实例,来加深 React Native 框架与 Android 平台混合开发的理解与运用。

12.2 Android 平台混合开发原理详解

我们按照学习 iOS 平台混合开发的模式,这里我们继续结合一个小的实例来学习 React Native 平台与 Android 平台混合开发的原理与方法。

Android 平台的混合开发主要包含如下几个主要步骤:

  1. 在 Android 项目中通过原生代码实现提供给 React Native 调用的原生功能;
  2. 在 Android 项目中将编写好的功能模块进行注册;
  3. 定义功能模块的 Android 包;
  4. 在 React Native 项目中通过 JavaScript 代码调用混合开发实现的 Android 平台原生功能。

完整代码在本书配套源码的 12-02 文件夹。

12.2.1 Android 原生代码实现

先通过 React Native CLI 初始化一个空项目,项目名称为 NativeAndroidModule,项目初始化的流程如图 12-1 所示。



图 12-1 Android 混合开发项目初始化

使用 Android 平台的开发工具 Android Studio 打开项目文件夹中的 android 文件夹,在 Android Studio 中选择导入此文件夹即可,如图 12-2 所示。



图 12-2 Android Studio 导入项目

注意,如果你是第一次打开此项目文件夹,Android Studio 会自动下载 Gradle 并使用 Gradle 进行项目的构建,此过程要确保你的网络环境没有任何阻碍并需要耐心等待加载完毕,加载过程如图 12-3 所示。



图 12-3 Gradle 初始化并进行项目的构建

项目使用 Android Studio 导入后打开如图 12-4 所示。



图 12-4 Android Studio 打开项目后的项目结构

新建的 Android 原生平台的类需要继承于React Native 框架提供的父类 ReactContextBaseJavaModule,这里我们新建的类命名为 MyModule。

如果没有导入 ReactContextBaseJavaModule 的包,Android Studio 会提示你进行包的引入,如图 12-5 所示。



图 12-5 Android Studio 提示导入缺失的包

新建后的文件代码如下所示。

1. import com.facebook.react.bridge.ReactContextBaseJavaModule;
2.
3. public class MyModule extends ReactContextBaseJavaModule {
4.
5. }

在继承了 ReactContextBaseJavaModule 父类后,需要实现方法 getName 返回模块名称,并在添加了类的构造函数,以及实现了调用 Android 原生 API 保持屏幕常亮并关闭常亮的两个方法 keepScreenAwake 和 removeScreenAwake。完整的 MyModule.java 代码如下。

1.	package com.nativeandroidmodule;
2.
3. import com.facebook.react.bridge.ReactApplicationContext;
4. import com.facebook.react.bridge.ReactContextBaseJavaModule;
5. import com.facebook.react.bridge.ReactMethod;
6.
7. public class MyModule extends ReactContextBaseJavaModule {
8.
9. ReactApplicationContext reactContext;
10.
11. public MyModule(ReactApplicationContext reactContext) {
12. super(reactContext);
13. this.reactContext = reactContext;
14. }
15.
16. @Override
17. public String getName() {
18. return "MyModule";
19. }
20.
21. @ReactMethod
22. public void keepScreenAwake() {
23. getCurrentActivity().runOnUiThread(new Runnable() {
24. @Override
25. public void run() {
26. getCurrentActivity().getWindow().addFlags(
27. android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
28. }
29. });
30. }
31.
32. @ReactMethod
33. public void removeScreenAwake() {
34. getCurrentActivity().runOnUiThread(new Runnable() {
35. @Override
36. public void run() {
37. getCurrentActivity().getWindow().clearFlags(
38. android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
39. }
40. });
41. }
42. }

同样,其他的 Android 平台的原生方法都可以按照此形式进行添加,添加后即可在 React Native 的 JavaScript 代码中调用。

12.2.2 Android 原生模块注册

接下来我们需要创建一个类来实现 ReactPackage 的接口函数,实现原生模块的注册,这里我们命名此文件名为 MyModulePackage.java,并实现接口中的 createNativeModules 与createViewManagers 两个方法。这里我们使用函数 createNativeModules 来进行模块的注册,另一个函数 createViewManagers 进行空值返回即可。

最终的完整代码如下,注意代码第 19 行的定义。

1.	package com.nativeandroidmodule;
2.
3. import com.facebook.react.ReactPackage;
4. import com.facebook.react.bridge.NativeModule;
5. import com.facebook.react.bridge.ReactApplicationContext;
6. import com.facebook.react.uimanager.ViewManager;
7.
8. import java.util.ArrayList;
9. import java.util.Collections;
10. import java.util.List;
11.
12. public class MyModulePackage implements ReactPackage {
13. @Override
14. public List<NativeModule> createNativeModules(
15. ReactApplicationContext reactContext) {
16. List<NativeModule> modules = new ArrayList<>();
17.
18. modules.add(new
19. MyModule(reactContext));
20.
21. return modules;
22. }
23.
24. @Override
25. public List<ViewManager> createViewManagers(ReactApplicationContext
26. reactContext) {
27. return Collections.emptyList();
28. }
29. }

12.2.3 Android 包定义

在项目中的 MainApplication.java 文件中,需要包含上我们自己开发的原生包,添加在 getPackages 函数中即可。

1.	package com.nativeandroidmodule;
2.
3. import android.app.Application;
4.
5. import com.facebook.react.ReactApplication;
6. import com.facebook.react.ReactNativeHost;
7. import com.facebook.react.ReactPackage;
8. import com.facebook.react.shell.MainReactPackage;
9. import com.facebook.soloader.SoLoader;
10.
11. import java.util.Arrays;
12. import java.util.List;
13.
14. public class MainApplication extends Application implements ReactApplication {
15.
16. private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
17. @Override
18. public boolean getUseDeveloperSupport() {
19. return BuildConfig.DEBUG;
20. }
21.
22. @Override
23. protected List<ReactPackage> getPackages() {
24. return Arrays.<ReactPackage>asList(
25. new MainReactPackage(),
26. //包含上我们自定义的原生组件包
27. new MyModulePackage()
28. );
29. }
30.
31. @Override
32. protected String getJSMainModuleName() {
33. return "index";
34. }
35. };
36.
37. @Override
38. public ReactNativeHost getReactNativeHost() {
39. return mReactNativeHost;
40. }
41.
42. @Override
43. public void onCreate() {
44. super.onCreate();
45. SoLoader.init(this, /* native exopackage */ false);
46. }
47. }

包含的方式在代码的第 27 行,Android 原生端开发完毕后的文件结构如图 12-6 所示。



图 12-6 Android 端开发完毕文件结构

《React Native 精解与实战》书籍连载「Android 平台与 React Native 混合开发」的更多相关文章

  1. 《React Native 精解与实战》书籍连载「iOS 平台与 React Native 混合开发」

    此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...

  2. 《React Native 精解与实战》书籍连载「配置 iOS 与 Android 开发环境」

    此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...

  3. 《React Native 精解与实战》书籍连载「React Native 网络请求与列表绑定」

    此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...

  4. 《React Native 精解与实战》书籍连载「React Native 中的生命周期」

    此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...

  5. 《React Native 精解与实战》书籍连载「React Native 底层原理」

    此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...

  6. 《React Native 精解与实战》书籍连载「Node.js 简介与 React Native 开发环境配置」

    此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...

  7. 《React Native 精解与实战》书籍连载「React 与 React Native 简介」

    此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...

  8. [书籍精读]《React Native精解与实战》精读笔记分享

    写在前面 书籍介绍:本书由架构师撰写,包含ReactNative框架底层原理,以及与iOS.Android混合开发案例,精选了大量实例代码,方便读者快速学习.主要内容分为两大部分,第1部分" ...

  9. 《React Native 精解与实战》书籍连载「React Native 源码学习方法及其他资源」

    此系列文章将整合我的 React 视频教程与 React Native 书籍中的精华部分,给大家介绍 React Native 源码学习方法及其他资源. 最后的章节给大家介绍 React Native ...

随机推荐

  1. &lt;button&gt;和&lt;input type=&quot;button&quot;&gt; 的区别

    <button>标签 定义和用法 <button> 标签定义一个按钮. 在 button 元素内部,您可以放置内容,比如文本或图像.这是该元素与使用 input 元素创建的按钮 ...

  2. PHP系列之一traits的应用

    Traits 在PHP中实现在方法的重复使用:Traits与Class相似,但是它能够在Class中使用自己的方法而不用继承: Traits在Class中优先于原Class中的方法,引用PHP Doc ...

  3. 【OpenStack】OpenStack系列6之Sheepdog环境搭建

    准备 repo配置 yum clean all yum makecache yum install -y make automake autoconf gcc nss-devel wget git g ...

  4. 银行HR:寒门再难出贵子

    银行HR:寒门再难出贵子来源:金融行业网 2013 年 8 月 6 日 来源:天涯社区 作者:永乐大帝二世 本文是一位银行的HR写的,他工作了10年,接待了一群到银行实习的实习生,然后观察他们发生的好 ...

  5. java异常处理机制 (转载)

    java异常处理机制 本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点,从C ...

  6. Java判断字符串是中文还是英文

    在做开发的时候我们经常需要用到根据某个字符或者字符串来判断其是中文还是英文,从而做相应的处理,其实不难,大多数人们都是用到正则来判断的,下面小贝就给大家分享一下Java判断字符串是中文还是英文 推荐文 ...

  7. Linux SSH登录很慢的解决方法

    一:UseDNS OpenSSH在用户登录的时候会验证IP,它根据用户的IP使用反向DNS找到主机名,再使用DNS找到IP地址,最后匹配一下登录的IP是否合法.如果客户机的IP没有域名,或者DNS服务 ...

  8. cocos2d JS-(JavaScript) 函数类型相互转换(字符串、整形、浮点形、布尔值)

    工作忙好些天了,近段时间抽点空分享一下自己学习JS的一点笔记心得做点记录,大神勿喷,谢谢! 1.字符串的转化 var found = false; console.log(found.toString ...

  9. timescale

    `timescale 1ns/100ps     表示时延单位为1ns, 时延精度为100ps.`timescale 编译器指令在模块说明外部出现, 并且影响后面所有的时延值.

  10. ThinkPHP之文件上传

    在项目其中.我们有的时候需要上传图片的功能.简单的从面相过程的方法是相对较为复杂的,要一步一步的来.假设用框架的话,相对就简单了很多,主要就是方法以及每个变量所代表的意义,然后就是一些注意的地方了. ...