[React Native Android 安利系列]RN中使用js調用java代碼

歡迎你們收看react-native-android系列教程,跟着本系列教程學習,能夠熟練掌握react-native-android的開發,你值得擁有:java

https://segmentfault.com/blog...react

書接上節,咱們上節說道,如何控制原生android的activity間跳轉,此次,咱們試着用js去操控這個過程。android

1. 爲你的應用添加一個js可調用的java接口

既然要使用js去調用java,那咱們的第一步,固然是提供一個js能夠調用的java接口了。git

1.1 提供一個跳轉的函數

首先,照着上節的思路,咱們將activity之間的跳轉,封裝成一個函數,放在MainActivity裏面。以下:github

public class MainActivity extends ReactActivity {

    public void skip() {
        Intent intent = new Intent(this, DetailActivity.class);
        startActivity(intent);
    }
....
}

1.2 新建一個類,來存放咱們須要被調用的java代碼

緊接着咱們須要新建一個類(MyExtension)繼承自ReactContextBaseJavaModule這個抽象類,以後咱們新建的這個類,能夠承載咱們暴露給js的方法。讓咱們動手開始寫這個類吧。chrome

1.2.1 新建一個包---extension,如圖1.2.1

110823_v6iz_1177792.png
圖1.2.1segmentfault

1.2.2 在包下,新建一個類---MyExtension,如圖1.2.2

111032_lTl5_1177792.png
圖1.2.2react-native

代碼以下:app

package com.hellowreact.extension;

import android.content.Intent;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.hellowreact.DetailActivity;
import com.hellowreact.MainActivity;

/**
 * Created by baidu on 16/6/12.
 */
public class MyExtension extends ReactContextBaseJavaModule {
    public MyExtension(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @ReactMethod
    public void open() {
        MainActivity activity = (MainActivity) getCurrentActivity();
        activity.skip();
    }

    @Override
    public String getName() {
        return "MyExtension";
    }
}

這裏有幾個事項,注意一下:frontend

1. 咱們繼承自ReactContextBaseJavaModule這個抽象類

2. 咱們須要重寫getName方法,命名一下咱們的擴展。之後咱們能夠在js裏面按照名字找到這個擴展。

3. 咱們寫了一個open方法,這個方法是將來會導出到咱們的js中,並能夠被js調用的方法。

1.3 書寫註冊接口待用

咱們寫好了方法,接着咱們就要註冊了,咱們還在extension的包裏面,新建一個類(ExtensionPackage),代碼以下:

package com.hellowreact.extension;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created by baidu on 16/6/12.
 */
public class ExtensionPackage implements ReactPackage {
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new MyExtension(reactContext));
        return modules;
    }

    @Override
    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

此時,咱們的目錄結構看起來應該是這樣的,如圖1.3.1
111430_ggmk_1177792.png
圖1.3.1

1.4 將寫好的接口註冊到MainActivity中去

接着,咱們要在MainActivity中去註冊咱們寫好的這個接口。
打開咱們的MainActivity,其中有一個已經寫好的方法 --- getPackages,如圖1.4.1
111639_MrBw_1177792.png
圖1.4.1
咱們在其中,加入咱們寫好的接口(ExtensionPackage)

2 從新運行app,並在js中查看接口是否已經存在與js中

上述步驟完成以後,就意味着咱們的接口已經導出了,接下來咱們首先要驗證一下。咱們打開index.android.js並在require的模塊中,增長一個NativeModules(如圖2.1)
111942_5pb0_1177792.png
圖2.1

NativeModules中存放着咱們能夠調用的native模塊,還記得當時定義咱們的擴展時,起的名字是什麼嗎?
112207_1Ffr_1177792.png
圖2.2

對!就是"MyExtension",既然已經註冊好了,那麼咱們就在js中看看,是否已經有了呢?咱們挑一個地方(本例中使用的是在constructor裏)打印一下,看看是否已經有了呢(如圖2.3)。
112102_geIu_1177792.png
圖2.3

咱們使用debug js,在chrome中調起調試界面(若是還不會使用,咱們接下來的章節裏會詳細講解,跟着我看看變量便可,如圖2.4):
112532_kLo8_1177792.png
圖2.4

能夠看下圖2.5,咱們成功的看到了當時咱們導出的open函數:
112733_BcpG_1177792.png
圖2.5

good!!!

3 嘗試調用咱們導出的open方法

上一步中,咱們驚喜的看到咱們在java中定義的open方法已經能在控制檯看到了。接下來,咱們在點擊list的時候,去調用一下open方法:

class hellowReact extends Component {
  constructor(props) {
    console.log(NativeModules.MyExtension);
    super(props);
    var list = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    this.state = { 
      list: list.cloneWithRows(['hello', 'react', 'this', 'is', 'my', 'listView'])
    };  
  }
  oneRow(oneItem) {
    return <Text>{oneItem}</Text>;
  }
  seeDetail() {
    NativeModules.MyExtension.open();
  }
  render() {
    return (
      <View style={styles.container}>
        <ListView
          dataSource={this.state.list}
          renderRow={this.oneRow}
          onTouchEnd={this.seeDetail}
        />  
      </View>
    );  
  }
}

接着,咱們從新運行一下,效果如圖3.1與圖3.2
114239_Yeqf_1177792.png
圖3.1
114304_ZQmn_1177792.png
圖3.2

因而乎,咱們看到了運行的效果。下一章,咱們會一塊兒看看react-native中,js調用原生代碼的原理。

本文中所用的例子,能夠在這裏找到:

https://github.com/houyu01/re...

下一節,咱們將一塊兒討論一下,上述調用的RN底層原理,很是淺顯易懂,不要錯過:

原創文章,版權全部,轉載請註明出處

相關文章
相關標籤/搜索