Integration and Use of jpush-react-native Plug-ins in Android Papers

Preface



At present, although React Native updates faster, and various components provide a very comprehensive, but in some cases, hybrid development will quickly shorten the development cycle, the reason is that the "foundation" of the original platform is undoubtedly deeper, with many and rich types of third-party support libraries. In many cases, the use of these libraries can avoid forced duplication of labor. Next, let's take the following steps jpush-react-native plug-in Take, for example, how to use native third-party libraries in React Native.

start



Before you start, you must install the following software: npm command line tool, react-native command line tool, Android Studio. jpush-react-native is Jpush The React Native version plug-in provided allows us to quickly integrate push functions. In fact, the plug-in is a hybrid application that uses its own native SDK and encapsulates some interfaces so that developers can call each other between JS and native platforms. Next, we need only three steps to complete the application of most native libraries in React Native.

First, two concepts are defined. In Android Studio, a project often contains many modules, and the build.gradle configuration in the project generally works for all modules. build.gradle in Module configures the dependencies or tasks required by the Module, and so on.

Step 1 - Installation



Enter the React Native project from the command line, and then complete the installation of the jpush-react-native plug-in using the following two commands:

npm install jpush-react-native --save

rnpm link jpush-react-native

jpush-react-native is published to npm, so it's easy to install using the command line.

However, many third-party libraries may require native installation. For example, providing jar packages or aar packages is common in Android and may be installed in a maven-dependent manner. If it is installed in the above way, some adjustments need to be made:

  • The way jar packages or aar packages are:

i. Copy dependency packages to the libs folder of module (if not, you need to create them manually)

ii. Add in build.gradle:

android {
...
    sourceSets {    
        main {        
            jniLibs.srcDirs = ['libs']
        }
    }
...
}
...
dependencies {
    compile fileTree(dir: "libs", include: ["*.jar"])
}
  • In a maven-dependent manner:

i. Add in the build.gradle of the project:

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

ii. Add:

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

Where xxx refers to groupId, artifactId and version number (separated by: separated), it is generally given by the provider. For example, Active Android:

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

Step 2 - Adaptation (Configuration)



This step varies with third-party libraries. In fact, most of them are similar, and some libraries can be used directly without configuration. jpush-react-native still needs to be configured
First run the script on the command line:

// Replace AppKey and Modele Name with your own
npm run configureJPush [AppKey] [Module Name]
  • Configure Android Manifest
<meta-data android:name="JPUSH_CHANNEL" android:value="${APP_CHANNEL}"/>
<meta-data android:name="JPUSH_APPKEY" android:value="${JPUSH_APPKEY}"/>

Copy the above code to Android Manifest of your Module.

  • Configure build.gradle
    Open the build.gradle file at the same level as Android Manifest and make the following changes:
android {
...

    defaultConfig {
        // Change to your own package name
        applicationId "com.xxx"
        ...
        manifestPlaceholders = [        
            JPUSH_APPKEY: "xxx",  //Replace your AppKey here, Aurora Register app gets         
            APP_CHANNEL: "developer-default"      //Application Channel Number
        ]
    }
}

This configuration is complete.

The third step is to build bridges.



This step is the last and core step. "Bridge building" mainly provides some methods of @ReactMethod tag on the Native side, or callback to JS after processing in Native, which is to make JS and Native call each other. This is also the advantage of hybrid development. The libraries provided by the native platform can be used as long as we build a bridge. Just a little bit of native code can save most of our work. Many people who have just come into contact with React Native don't know how to open the JS interface in Native (as we all know, the JS interface consists of a Component and has its own routing system). After that, I will write a simple example, declare the registration interface in Native way (Activity in Android), and then use JS. Rendering the interface, this problem will be solved. Next, let's look at the example of jpush-react-native.

First create a ManiActivity and MainApplication class under your Module. After RN 0.29, native modules need to be added to MainApplication.

MainActivity.java

public class MainActivity extends ReactActivity implements DefaultHardwareBackBtnHandler {

    @Override
    protected String getMainComponentName() { 
        // The name returned here should be the same as the Component name registered on the JS side.
        return "PushDemoApp";
    }
    
    @Override
    protected void onPause() {    
        super.onPause();    
        JPushInterface.onPause(this);
    }
    
    @Override
    protected void onResume() {    
        super.onResume();    
        JPushInterface.onResume(this);
    }
}

Next, you need to add native modules to 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;    
    }
}

That's it. Looking at sync in Android Studio, you can see that jpush-react-native is imported as Library Module. Open the JPushModule class and see the onReceive method in it. Notification processing is in this block. After the Aurora Push Background sends a notification (or use the server sdk), the client SDK receives the notification and calls back to the onReceive method. Some customized operations can be done in onReceive. For example, after receiving the notification, click on the notification to open a specific interface:

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, "The user clicks to open the notification");
        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);
        // If you need to jump to the specified interface, you need to start MainActivity and SecondActivity at the same time:
        // 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};
        // Start MainActivity and SecondActivity at the same time
        context.startActivities(intents);
        // Or call back a method of JS
    }
}

...

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

In the example above, when we receive a click notification event, we open a specific interface. This interface is created in Native (the advantage of doing so is that it can also implement some specific requirements, such as when notified, if there is Second Activity, then all the interfaces that are above Second Activity pop up, if not, create and so on), but it is still rendered with JS code. Dyeing interface, which is very good for students familiar with JS. To do this, we first create a Second Activity class:

SecondActivity.java

public class SecondActivity extends ReactActivity {

    @Override
    protected String getMainComponentName() {
        // Notice that the name corresponds to JS in Component 
        // The first parameter of the AppRegistry.registerComponent method is the same
        return "SecondActivity";
    }
}

Then register Second Activity at Android Manifest:

AndroidManifest

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

Under the React Native project, create a new folder react-native-android for storing JS-related files. New second.js file:

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);

In this way, great success! Next, you can register routes in index.android.js so that you can jump to this interface in JS. Source code stamp here

summary

This is the general process of developing applications in a hybrid way in React Native. In this way, you can use rich third-party libraries of native platforms immediately, but you need to write some code in the Native section, but the cost is much less than the way you use JS to implement it again.

Author: Ken Choi - Aurora
Original: Integration and Use of jpush-react-native Plug-ins in Android Papers
KNOWLEDGE COLUMN: Aurora Daily

Keywords: Android React Gradle npm

Added by CookieDoh on Tue, 02 Jul 2019 23:38:09 +0300