RN开发Android解决前让我头大的问题

581 阅读6分钟

公众号:暮北林

Q Q 群 : 一起学前端

记录那些在Android中未解决前让我头大的问题

项目情况

最近有两个关于ReactNative做的Android的项目

1.一个通过串口、TCP通信对硬件的控制

2.一个是WebRTC的Webview

面临的问题

1. 开机自启
2. 全屏显示(隐藏statusBar navigationBar)
3. 串口通信
4. 获取本地IP(有线网络的ip)
5. 选项卡切换卡顿(5s才能渲染)/性能问题
6. 下载文件到U盘

7. Webview不信任SSL证书
8. Webview不能自动播放视频
9. 。。。

如何解决的问题

1. 开机自启问题

// 由于自己没有做过Android开发这个问题困惑了好久 查文档关键字都不确定, 还好最后还是解决了
// 总体流程分为两步1. 接收开机广播 2. 接收到广播后启动Activity
// 1.在java/com/project下新建bootBroadcastReceiver.java
package com.record; // 这里是我的项目包名 每个人都不一样
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class BootBroadcastReceiver extends BroadcastReceiver {
    static final String ACTION = "android.intent.action.BOOT_COMPLETED"// 开机完成
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(ACTION)) {
            Intent mainActivityIntent = new Intent(context, MainActivity.class);  // 要启动的Activity
            mainActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(mainActivityIntent);
        }
    }
}
// 2.AndroidManifest.xml中加入/注册接收
<receiver android:name="com.record.BootBroadcastReceiver" // 这里对应广播接收的类名
    android:enabled="true"
    android:exported="true"
    android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
        <intent-filter android:priority="2147483647"//这里是权重我写的是最高的
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <category android:name="android.intent.category.LAUNCHER" />
            <category android:name="android.intent.category.HOME" />
        </intent-filter>
</receiver>

2.全屏显示问题

// 全屏显示不仅仅是隐藏statusBar和navagationBar
// 在软键盘弹起是会把navagationBar给带出来 软键盘收起是还要继续隐藏
// 这部分内容可以在Android开发者文档中找到说明
// MainActivity.java中声明一个hideNavagation函数

 private void hideNavigationBar() {
    int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
    | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
    getWindow().getDecorView().setSystemUiVisibility(uiOptions);
  }

// 在需要全屏的时候调用就OK了
// 何时调用呢? 1. onCreate的时候 2. UI变化的时候(软键盘会引起界面的变化)
@Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    hideNavigationBar();

    View decorView = getWindow().getDecorView();
    decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
        @Override
        public void onSystemUiVisibilityChange(int visibility) {
          hideNavigationBar();
        }
    });
  }

3. 串口通信问题

这个只能依赖第三方的插件库
目前我使用的是这个库:https://github.com/bastengao/react-native-serial-port-api
当时使用还有一些错误github上提了issue并找到了作者的微博给大佬沟通后修改发布了1.1.0版本
正常使用了为了感谢给大佬买了一杯咖啡Thanks♪(・ω・)ノ。。。

看下具体的使用代码

  let serialPath = '/dev/ttyS4';
  let serlialPort = SerialPortAPI.open(serialPath, { baudRate115200dataBits8stopBits1parity0 }).then(serialPort => {
      //  Toast.success(`串口${serialPath}链接成功`, 2);
      // 监听接收数据
      this.sub = serialPort.onReceived(buff => {
         let data = buff.toString('hex');
      })
      // 发送数据
      serialPort.send('C06162C3C0').then(res => {
          // if (res) {
          //   Toast.success('发送串口数据成功')
          // }
      }).catch(err => {
         console.log(err);
      })
   }).catch(err => {
      Toast.fail(`串口${serialPath}链接失败`1)
   })

4. 获取本机有线IP

这个问题一直没有得到解决但是后来做另一个Electron的项目得到了另一种解决方案
//代码有点长就不写了 直接看广播获取的ip和ifconfig得到的ip做一个对照
$node boardcast.js 
{ address: '192.168.0.108', family: 'IPv4', port: 19991, size: 21 }

$ifconfig | grep inet
    inet 127.0.0.1 netmask 0xff000000 
    inet6 ::1 prefixlen 128 
    inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
    inet6 fe80::86:f9f3:1a29:fa05%en0 prefixlen 64 secured scopeid 0x4 
    inet 192.168.0.108 netmask 0xffffff00 broadcast 192.168.0.255
    inet6 fe80::c068:abff:feae:7ab7%awdl0 prefixlen 64 scopeid 0x8 
    inet6 fe80::c068:abff:feae:7ab7%llw0 prefixlen 64 scopeid 0x9 
    inet6 fe80::9188:920e:25c:508f%utun0 prefixlen 64 scopeid 0xa 
    inet6 fe80::b76c:3efa:7a58:a35c%utun1 prefixlen 64 scopeid 0xb

5.选项卡切换卡顿问题

RK3399手机上安兔兔的跑分结果显示打败了1%的手机 但是需求是必须流畅 又受制于不是原生开发必须流畅是不可能了只能尽可能流畅了
// 问题原因
不流畅的原因就是手机性能不行
// 解决思路
尽可能的减少渲染内容  该呈现的内容一点也不能少
// 解决方案
1.  1 | 2 | 3 | 4 | 5 // 5个选项卡只显示当前的和其两侧的内容  其他的全部是空组件
2. 当3显示时 当前有内容的组件为234 其余全是空组件
3. 既能显示当前组件 又可以在左右滑动的时候 有快速的渲染
// 成效  
按照以上的解决方法改造  从5s的渲染耗时降低到1s可完整显示Tab的内容

6. 下载文件到U盘

1. 最优方案 检测U盘的插拔直接把文件写入U盘 有参照的例子如迅雷下载可以直接下载到U盘
2. 困难点 RN没有可用的插件  无原生开发能力
最终选择了妥协 由前端发送download命令告知C_server进行下载操作

7.Webview相关

Webview项目需求是做一个WebRTC的Android项目 又需要在RTC流上进行AI识别 RN stream上无法进行截图操作 只能选择Webview
1. SSL如何跳过
   @Override
    public void onReceivedSslError(final WebView webView, final SslErrorHandler handler, final SslError error) {
        handler.cancel();// 修改为以下代码
        handler.proceed(); // 忽略SSL继续执行
    }

2. 视频无法自动播放
mediaPlaybackRequiresUserAction
布尔值,控制 HTML5 音频和视频播放前是否需要用户点击。默认为true设置为false即可

写在最后

关于RN开发Android应用因为不懂Android开发以后还会其他问题 一点一点的不断积累吧

我的公众号和QQ群


公众号
公众号