jpush-react-native 插件的集成與使用 Android 篇

来源:http://www.cnblogs.com/jpush88/archive/2017/05/08/6826221.html
-Advertisement-
Play Games

前言 當前 React Native 雖說版本更新比較快,各種組件也提供的很全面了,但是在某些情況下,混合開發的方式才會快速縮短開發周期,原因無非就是原生平臺的“底蘊”無疑更深,擁有眾多且類型豐富的第三方支持庫。很多情況下,運用這些庫可以避免苦逼的重覆勞動。接下來我們以 "jpush react n ...


前言



當前 React Native 雖說版本更新比較快,各種組件也提供的很全面了,但是在某些情況下,混合開發的方式才會快速縮短開發周期,原因無非就是原生平臺的“底蘊”無疑更深,擁有眾多且類型豐富的第三方支持庫。很多情況下,運用這些庫可以避免苦逼的重覆勞動。接下來我們以 jpush-react-native 插件為例來看看在 React Native 中如何使用原生的第三方庫。

開始



在開始之前,你必須安裝以下軟體:npm 命令行工具,react-native 命令行工具, Android Studio。jpush-react-native 是極光推送提供的 React Native 版本插件,可以讓我們快速集成推送功能。實際上這個插件就是一個混合應用,使用他們自己的原生 SDK,並且封裝了一些介面,讓開發者可以在 JS 和原生平臺之間互相調用。接下來我們只需要三個步驟就可以完成絕大多數原生庫在 React Native 中的應用。

先明確兩個概念,在 Android Studio 中一個項目往往會包含很多模塊(Module),項目中的 build.gradle 配置一般對所有 module 生效。而 Module 中的 build.gradle 則配置了該 Module 所需的依賴或者任務等等。

第一步——安裝



在命令行中進入 React Native 項目,然後使用如下兩個命令即可完成 jpush-react-native 插件的安裝:

npm install jpush-react-native --save

rnpm link jpush-react-native

jpush-react-native 發佈到 npm 了,所以使用命令行可以輕鬆安裝。

然而有很多第三方庫可能需要原生的安裝方式。比如提供 jar 包或者 aar 包的方式在 Android 中很常見,也有可能以 maven 依賴的方式安裝。如果是以上方式安裝需要做一些調整:

  • jar 包或者 aar 包的方式:

i. 將依賴包複製到 module 的 libs 文件夾下(如果沒有則需要手動創建)

ii. 在 build.gradle 中添加:

android {
...
    sourceSets {    
        main {        
            jniLibs.srcDirs = ['libs']
        }
    }
...
}
...
dependencies {
    compile fileTree(dir: "libs", include: ["*.jar"])
}
  • 以 maven 依賴的方式:

i. 在項目的 build.gradle 中增加:

allprojects {    
    repositories {
        ...        
        mavenCentral()        
        maven {            
            url "https://oss.sonatype.org/content/repositories/snapshots/"        
        }    
    }
}

ii. 在 module 的 build.gradle 中添加:

dependencies {
...
compile 'xxx-SNAPSHOT'
}

其中的 xxx 指代 groupId、artifactId 以及版本號(以 : 分隔),一般都會由提供方給出。比如 ActiveAndroid:

compile 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT'

第二步——適配(配置)



這一步因第三方庫而異,其實大多都是大同小異,有的庫甚至不需要配置直接可以“搭建橋梁”使用。jpush-react-native 還是要配置一下的
首先在命令行中運行腳本:

// 將 AppKey 和 Module Name 替換成自己的
npm run configureJPush [AppKey] [Module Name]
  • 配置 AndroidManifest
<meta-data android:name="JPUSH_CHANNEL" android:value="${APP_CHANNEL}"/>
<meta-data android:name="JPUSH_APPKEY" android:value="${JPUSH_APPKEY}"/>

將以上代碼複製到你 Module 的 AndroidManifest 下即可。

  • 配置 build.gradle
    打開與 AndroidManifest 同級的 build.gradle 文件,做以下改動:
android {
...

    defaultConfig {
        // 換成自己的包名
        applicationId "com.xxx"
        ...
        manifestPlaceholders = [        
            JPUSH_APPKEY: "xxx",  //在此替換你的AppKey,極光官網註冊應用獲得         
            APP_CHANNEL: "developer-default"      //應用渠道號
        ]
    }
}

到此配置完成。

第三步 搭建橋梁



這一步是最後也是最核心的一步。“搭建橋梁”主要是在 Native 側提供一些 @ReactMethod 標簽的方法,或者在 Native 中處理後回調到 JS,說白了就是要使得 JS 和 Native 可以相互調用。這也是混合開發的優勢所在,原生平臺提供的庫,我們只需要搭建一下橋梁,就可以拿來使用。只要稍微寫一點原生的代碼,可以省去我們絕大部分工作。許多剛接觸 React Native 的人不知道如何在 Native 中打開 JS 的界面(眾所周知,JS 的界面由一個個 Component 組成,有自己的路由系統)後面我會寫一個簡單例子,用 Native 的方式聲明註冊界面(在 Android 中即為 Activity),然後用 JS 渲染界面,這個問題就迎刃而解了。接下來還是先看看 jpush-react-native 的例子。

首先在你的 Module 下創建一個 ManiActivity 以及 MainApplication 類。RN 0.29 後,需要在 MainApplication 中添加原生模塊。

MainActivity.java

public class MainActivity extends ReactActivity implements DefaultHardwareBackBtnHandler {

    @Override
    protected String getMainComponentName() { 
        // 這裡返回的名字要與 JS 側註冊的 Component 名字一致
        return "PushDemoApp";
    }
    
    @Override
    protected void onPause() {    
        super.onPause();    
        JPushInterface.onPause(this);
    }
    
    @Override
    protected void onResume() {    
        super.onResume();    
        JPushInterface.onResume(this);
    }
}

接下來需要在 MainApplication 中增加原生模塊

MainApplication.java

public class MainApplication extends Application implements ReactApplication {    

    private boolean SHUTDOWN_TOAST = false;    
    private boolean SHUTDOWN_LOG = false;    

    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {        
        @Override        
        protected boolean getUseDeveloperSupport() {            
            return BuildConfig.DEBUG;        
        }        

        @Override        
        protected List<ReactPackage> getPackages() {            
            return Arrays.<ReactPackage>asList(                    
                new MainReactPackage(),                    
                new JPushPackage(SHUTDOWN_TOAST, SHUTDOWN_LOG)              
            );        
        }    
    };    

    @Override    
    public ReactNativeHost getReactNativeHost() {        
        return mReactNativeHost;    
    }
}

這樣就完成了。在 Android Studio 中 sync 一下,可以看到 jpush-react-native 作為 Library Module 導進來了。打開 JPushModule 類,看到其中的 onReceive 方法,通知的處理都在這一塊。在極光推送後臺發送通知(也可以使用 服務端 sdk)後,客戶端 sdk 收到通知後會回調到 onReceive 方法,在 onReceive 中可以做一些定製化的操作。比如收到通知後,點擊通知打開特定的界面:

public static class JPushReceiver extends BroadcastReceiver {    
    public JPushReceiver() {        
        HeadlessJsTaskService.acquireWakeLockNow(mRAC);    
    }    
    
    @Override    
    public void onReceive(Context context, Intent data) {
    ...
    } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(data.getAction())) {    
        Logger.d(TAG, "用戶點擊打開了通知");
        Intent intent = new Intent();
        intent.setClassName(context.getPackageName(), context.getPackageName() + ".MainActivity");
        intent.putExtras(bundle);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        // 如果需要跳轉到指定的界面,那麼需要同時啟動 MainActivity 及指定界面(SecondActivity):
        // If you need to open appointed Activity, you need to start MainActivity and
        // appointed Activity at the same time.
        Intent detailIntent = new Intent();
        detailIntent.setClassName(context.getPackageName(), context.getPackageName() + ".SecondActivity");
        detailIntent.putExtras(bundle);
        Intent[] intents = {intent, detailIntent};
        // 同時啟動 MainActivity 以及 SecondActivity
        context.startActivities(intents);
        // 或者回調 JS 的某個方法
    }
}

...

 @ReactMethod
    public void finishActivity() {
        Activity activity = getCurrentActivity();
        if (activity != null) {
            activity.finish();
        }
    }

上面的例子中,我們在收到點擊通知的事件時,打開一個特定的界面。這個界面在 Native 中創建(這樣做的好處在於還可以實現一些特定的需求,比如收到通知後,如果存在 SecondActivity,則讓位於 SecondActivity 之上的界面全部彈出,如果不存在,則創建等等之類的需求),但是還是用 JS 的代碼來渲染界面,這對於熟悉 JS 的同學來說,再好不過。要做到這一點,首先我們創建一個 SecondActivity (與 MainActivity 同級)類:

SecondActivity.java

public class SecondActivity extends ReactActivity {

    @Override
    protected String getMainComponentName() {
        // 註意這個名字與 JS 對應的 Component 中 
        // AppRegistry.registerComponent 方法的第一個參數相同
        return "SecondActivity";
    }
}

然後在 AndroidManifest 註冊 SecondActivity:

AndroidManifest

<activity android:name=".SecondActivity" />

在 React Native 項目下新建一個文件夾 react-native-android,專門用來存放 js 相關的文件。新建 second.js 文件:

second.js

'use strict';

import React from 'react';
import ReactNative from 'react-native';

const {
  AppRegistry,
  View,
  Text,
  TouchableHighlight,
  StyleSheet,
  NativeModules,
} = ReactNative;

var JPushModule = NativeModules.JPushModule;


export default class second extends React.Component {
  constructor(props) {
    super(props);
  }

  onBackPress = () => {
    let navigator = this.props.navigator;
    if (navigator != undefined) {
      this.props.navigator.pop();
    } else {
      console.log("finishing second activity");
      JPushModule.finishActivity();
    }
  }

  onButtonPress = () => {
    console.log("will jump to setting page");
    let navigator = this.props.navigator;
    if (navigator != undefined) {
      this.props.navigator.push({
        name: "setActivity"
      });
    } else {

    }

  }

  render() {
    return (
      <View>
        <TouchableHighlight
          style={styles.backBtn}
          underlayColor = '#e4083f'
          activeOpacity = {0.5}
          onPress = {this.onBackPress}>
          <Text>
            Back
          </Text>
        </TouchableHighlight>
        <Text
          style={styles.welcome}> 
          Welcome ! 
        </Text> 
        <TouchableHighlight underlayColor = '#e4083f'
          activeOpacity = {0.5}
          style = {styles.btnStyle}
          onPress = {this.onButtonPress}>
          <Text style={styles.btnTextStyle}>
            Jump To Setting page!
          </Text> 
        </TouchableHighlight>
        </View>
    );
  }
}

var styles = StyleSheet.create({
  backBtn: {
    padding: 10,
    marginTop: 10,
    marginLeft: 10,
    borderWidth: 1,
    borderColor: '#3e83d7',
    backgroundColor: '#3e83d7',
    borderRadius: 8,
    alignSelf: 'flex-start'
  },
  welcome: {
    textAlign: 'center',
    margin: 10,
  },
  btnStyle: {
    marginTop: 10,
    borderWidth: 1,
    borderColor: '#3e83d7',
    borderRadius: 8,
    backgroundColor: '#3e83d7',
    alignSelf: 'center',
    justifyContent: 'center'
  },
  btnTextStyle: {
    textAlign: 'center',
    fontSize: 25,
    color: '#ffffff'
  },
});

AppRegistry.registerComponent('SecondActivity', () => second);

就這樣,大功告成!接下來可以在 index.android.js 中註冊路由,使得在 JS 中也可以跳轉到這個界面。源碼請戳這裡

總結

以上就是在 React Native 中以混合的方式開發應用的大概過程。用這種方式可以馬上使用豐富的原生平臺第三方庫,只是在 Native 部分需要寫些代碼,但是花費的代價遠遠小於自己用 JS 的方式再實現一遍。


作者:KenChoi - 極光
原文:jpush-react-native 插件的集成與使用 Android 篇
知乎專欄:極光日報


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • history.back(-1):直接返回當前頁的上一頁,數據全部消息,是個新頁面 history.go(-1):也是返回當前頁的上一頁,不過表單里的數據全部還在 ...
  • #myCarousel img{ width: 100%; height: 100%; object-fit: cover; } ...
  • 1 /* 遮罩插件 2 * 可選選項 3 * smBoxBg 小方格遮罩顏色 預設 #FFFFFF 4 * backgroudColor 大遮罩顏色 預設 #000000 5 * backgroundImage 動態圖片 預設 loading.gif 6 * text 文字信息 預設 載入中.... ...
  • 背景 很多很多傳統的Web開發者還在用著傳統的jquery和ES5,大家都知道現在的前端如火如荼,但是眼花繚亂的框架和層出不窮的新概念,讓很多人無從下手,本文從0開始,帶你一步步由jquery操作DOM轉型成為一個新思想的前端開發者。沒有過多的引申和概念解釋。先上手實踐,再回頭體會。讓我們開始。(本 ...
  • localStorage是HTML5在在客戶端存儲數據的新方法,存儲的數據沒有時間限制。 localStorage的主要API: localStorage.setItem(key,value); key是保存數據的變數,value是保存的數據 localStorage.getItem(key); 讀 ...
  • 首先可能需要安裝npm,並且配置環境. 1.打開Dos(命令提示符).按Windows徽標鍵+R組合鍵,輸入cmd然後按回車鍵進入Dos. 2.安裝Yeoman.在Dos下輸入npm install -g yo. 3.安裝Grunt.在Dos下輸入npm install -g grunt-cli. ...
  • URL Schemes URL Schemes是蘋果給出的用來跳轉到系統應用或者跳轉到別人的應用的一種機制。同時還可以在應用之間傳數據。 設置一個URL Schemes:選中App工程->Info->URL Types里添加,可以添加多個。 在Info.plist里是這樣的: 打開App的代碼是這樣 ...
  • iOS 使用 UIMenuController 且不隱藏鍵盤的方法 在鍵盤顯示的時候使用 UIMenuController 彈出菜單,保持鍵盤顯示且可輸入的狀態。 實現方法有 1. 修改響應鏈(推薦) 2. 遵循 UIKeyInput 協議 3. 自定義 Menu controller 前兩種方法的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...