【简述RN集成到Android原生项目】
【Android项目集成RN系列:RN混淆 / 消息通信 / Gif图片/ 修改端口号 / 离线包】
【RN使用Android原生控件或自定义组件】

1. Linking 唤起APP.

  • 检查该app能否被唤起,也就是检查该app是否已安装成功;
    Linking提供了canOpenURL(url: string): Promise;这个方法,用来检测某个url是否可以打开;
     Linking.canOpenURL('appscheme://').then(canopen => {      ...    })
  • 唤起并传递参数。
    使用Linking打开app调用openURL方法即可:
    Linking.openURL('appscheme://apphost/path?params=xxx')
    完整调用方法如下:
      Linking.canOpenURL('appscheme://').then(canopen => {    if (canopen) {       console.warn('可以打开: appscheme');       Linking.openURL('appscheme://apphost/path?rn=true')    } else {       console.warn('未安装: appscheme');    }  })
    备注: Android人员应该知道上述打开的路由appscheme://apphost/path?rn=true 哪里来的,非Android应该不太清楚,其实这里的路由是我们在Android项目中的AndroidManifest.xml 文件中设置的,如下:
                                                                        

2. APP中唤起RN页面的Activity,并将路由信息通过linking传递到对应的js中。

  • APP中跳转加载RN的页面。
    Intent intent1 = new Intent(Intent.ACTION_VIEW, Uri.parse("appscheme://apphost/path?params=xxx"));startActivity(intent1);
  • RN页面渲染的js文件中如何获取跳转路由。
         Linking.getInitialURL().then((url) => {          if (url) {            console.warn('捕捉的URL地址为: ' + url);          }else{            console.warn('捕获得的url为空');          }     }).catch(err => console.error('错误信息为:', err));
  • 在js中监听APP的运行状态。
         AppState.addEventListener('change',(appState)=>{          if(appState=='active'){              Linking.getInitialURL().then(url=>{                  console.warn('stateChange url: ' + url);                  })          }        })
    监听的字符串以及状态如下:
    export type AppStateEvent = "change" | "memoryWarning";export type AppStateStatus = "active" | "background" | "inactive";

3. Linking在Android中使用Linking.getInitialURL()可能会返回null的问题。

在项目目录中node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java查看Linking的源码发现getInitialURL()方法如下:

@ReactMethodpublic void getInitialURL(Promise promise) { try {   Activity currentActivity = getCurrentActivity();   String initialURL = null;   if (currentActivity != null) {     Intent intent = currentActivity.getIntent();     String action = intent.getAction();     Uri uri = intent.getData();     if (Intent.ACTION_VIEW.equals(action) && uri != null) {       initialURL = uri.toString();     }   }   promise.resolve(initialURL);  } catch (Exception e) {   promise.reject(new JSApplicationIllegalArgumentException(       "Could not get the initial URL : " + e.getMessage()));  } }

由上述代码发现getInitialURL()方法获取的即为intent.getData().toString()内容,可是使用过程中发现此处返回可能为null,所以就跟着查看下原因,发现在React Native中的componentDidMount生命周期方法与Android的Activity还未建立绑定关系,此时 getCurrentActivity()返回null,所以拿不到对应的intent.getData()。

解决方案:

  1. 方案一:
    在RN中对AppState进行监听,当处于active状态再获取对应的url。
     onAppStateChange = (nextAppState) => {     if (nextAppState === 'active') {       Linking.getInitialURL().then(url => {         console.warn("onAppStateChange Url:"+url)       })     }   }   componentDidMount = async () => {     if (AppState.currentState === 'active') {       Linking.getInitialURL().then(url => {         console.warn("AppState.currentState Url:"+url)       })     }     AppState.addEventListener('change', this.onAppStateChange); }
  2. 方案二:
    在Android中对应的Activity和NativeModule中修改。
    public static ArrayBlockingQueue myBlockingQueue = new ArrayBlockingQueue(1);//临时和RN交互的数据   @Override   protected void onCreate(Bundle savedInstanceState) {       super.onCreate(savedInstanceState);       if (getIntent() != null && getIntent().getData() != null){           myBlockingQueue.clear();           myBlockingQueue.add(getIntent().getData().toString());       }   }
    在NativeModule中添加如下方法:
    @ReactMethod    public void getInitialURL(Promise promise) {        try {            String initialURL = RNPreloadActivity.myBlockingQueue.take();            if (promise != null){                promise.resolve(initialURL);            }        } catch (InterruptedException e) {            if (promise != null){                promise.reject(new JSApplicationIllegalArgumentException(                 "Could not get the initial URL : " + e.getMessage()));            }        }    }

更多相关文章

  1. Android问题集锦之十:Android导入项目时Android jar包丢失的解决
  2. Android LayoutInflater inflate方法效率
  3. Android视频播放项目总结之 使用第三方Vitamio库,开发万能播放器(
  4. 下载Android Sdk源码方法
  5. 基于Android的WiFi对讲机项目简介
  6. 10个经典的Android开源项目(附源码包)

随机推荐

  1. Android(安卓)系统功能设置菜单 LinearLa
  2. Android完全(退出)关闭应用程序
  3. Android(安卓)调用J2EE webservice
  4. Android(安卓)Studio 开启调试 时 提示:co
  5. Android(安卓)TableLayout数据列表的回显
  6. android Beam
  7. 沉浸式状态栏的实现
  8. Android(安卓)Http Get/Post提交请求
  9. 七、Android数据链接更新路由表
  10. android > TabActivity ( actvity 切换 i