歡迎你們收看react-native-android系列教程,跟着本系列教程學習,能夠熟練掌握react-native-android的開發,你值得擁有:java
https://segmentfault.com/blog...react
書接上節,咱們上節說道,如何控制原生android的activity間跳轉,此次,咱們試着用js去操控這個過程。android
既然要使用js去調用java,那咱們的第一步,固然是提供一個js能夠調用的java接口了。git
首先,照着上節的思路,咱們將activity之間的跳轉,封裝成一個函數,放在MainActivity裏面。以下:github
public class MainActivity extends ReactActivity { public void skip() { Intent intent = new Intent(this, DetailActivity.class); startActivity(intent); } .... }
緊接着咱們須要新建一個類(MyExtension)繼承自ReactContextBaseJavaModule這個抽象類,以後咱們新建的這個類,能夠承載咱們暴露給js的方法。讓咱們動手開始寫這個類吧。chrome
圖1.2.1segmentfault
圖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調用的方法。
咱們寫好了方法,接着咱們就要註冊了,咱們還在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
圖1.3.1
接着,咱們要在MainActivity中去註冊咱們寫好的這個接口。
打開咱們的MainActivity,其中有一個已經寫好的方法 --- getPackages,如圖1.4.1
圖1.4.1
咱們在其中,加入咱們寫好的接口(ExtensionPackage)
上述步驟完成以後,就意味着咱們的接口已經導出了,接下來咱們首先要驗證一下。咱們打開index.android.js並在require的模塊中,增長一個NativeModules(如圖2.1)
圖2.1
NativeModules中存放着咱們能夠調用的native模塊,還記得當時定義咱們的擴展時,起的名字是什麼嗎?
圖2.2
對!就是"MyExtension",既然已經註冊好了,那麼咱們就在js中看看,是否已經有了呢?咱們挑一個地方(本例中使用的是在constructor裏)打印一下,看看是否已經有了呢(如圖2.3)。
圖2.3
咱們使用debug js,在chrome中調起調試界面(若是還不會使用,咱們接下來的章節裏會詳細講解,跟着我看看變量便可,如圖2.4):
圖2.4
能夠看下圖2.5,咱們成功的看到了當時咱們導出的open函數:
圖2.5
good!!!
上一步中,咱們驚喜的看到咱們在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
圖3.1
圖3.2
因而乎,咱們看到了運行的效果。下一章,咱們會一塊兒看看react-native中,js調用原生代碼的原理。
本文中所用的例子,能夠在這裏找到:
https://github.com/houyu01/re...
下一節,咱們將一塊兒討論一下,上述調用的RN底層原理,很是淺顯易懂,不要錯過:
原創文章,版權全部,轉載請註明出處