ReactNative了解(android)

来源:互联网 发布:元旦网络营销策划方案 编辑:程序博客网 时间:2024/06/06 12:49

ReactNative了解(android)

本文旨在对android 端的组件进行定制化,android原生中的实现方式,以及说明原生代码与js的交互过程

组件定制

以下的自定义模块都要加入一个ReactPackage,ReactPackage需要加入一个ReactNativeHost,这个步骤不做具体的说明,在以下的说明中都略过.在js中也需要进行必要的模块导入,相当于java中的包导入,也一起略过

在看组件定制之前先简单的了解下类的依赖关系.才知道组件可以怎么定制.

类图关系

View 定制

//本地的自定View,没有任何特殊的地方,与普通的自定义View是一样的public class CustomView extends View {    private String mText = "";    public CustomView(Context context) {        super(context);    }    public CustomView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);    }    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        Paint paint = new Paint();        paint.setTextSize(50);        paint.setColor(Color.RED);        canvas.drawText(mText,0,100,paint);    }    public void setText(String text){        mText = text;        invalidate();    }}//再通过ViewManager包装一下:public class MyViewManager extends SimpleViewManager<CustomView> {    @Override    public String getName() {        return "Custom";    }    @Override    protected CustomView createViewInstance(ThemedReactContext reactContext) {        return new CustomView(reactContext);    }//     通过@ReactProp(或@ReactPropGroup)注解来导出属性的设置方法    @ReactProp(name = "text")    public void setText(CustomView view,  @Nullable String text) {        view.setText(text);    }}

js端进行调用

var requireNativeComponent = require('requireNativeComponent');var Custom = {    name:"Custom",    propTypes:{        text:PropTypes.string,        ...View.propTypes    },};var Customview = requireNativeComponent('Custom', Custom);class HelloWorldApp extends Component {  render() {     if (Platform.OS === 'android') {      TouchableElement = TouchableNativeFeedback;    }    let diaplayText = this.state.text;    return (    <View style={styles.container}>         <Customview  text= "test" style={{width: 100, height: 100}} />   </View>    );  }}

NativeModule定制

public class MyModule extends ReactContextBaseJavaModule {    public Context mContext;    public MyModule(ReactApplicationContext reactContext) {        super(reactContext);        mContext = reactContext;    }    @Override    public String getName() {        return "MyModule";    }    @ReactMethod    public void jump() {        Intent intent = new Intent();        intent.setClass(mContext, SecondActivity.class);        mContext.startActivity(intent);    }    @ReactMethod    public void test() {        Toast.makeText(mContext,"test",Toast.LENGTH_SHORT).show();    }}

js端进行调用

export default class AwesomeProject extends Component {  gotoSecond(){         NativeModules.MyModule.jump();   }  render() {    var TouchableElement = TouchableHighlight;    if (Platform.OS === 'android') {      TouchableElement = TouchableNativeFeedback;    }    return (      <View style={styles.container}>        <Text style={styles.welcome}>          Welcome to React Native!        </Text>        <Text style={styles.instructions}>          To get started, edit index.android.js         </Text>        <Text style={styles.instructions}>          Double tap R on your keyboard to reload,{'\n'}          Shake or press menu button for dev menu        </Text>        <TouchableElement          onPress={this.gotoSecond}        >          <Text style={styles.instructions}>               点我点我          </Text>        </TouchableElement>      </View>    );  }}

JsModule定制 (官网上并没有说我该怎么弄)

//java端,需要配置与js端一样的接口public interface MyJsModule extends JavaScriptModule {     String getText(String string);} //java端调用  String text =  mReactInstanceManager.getCurrentReactContext().getJSModule(MyJsModule.class).getText("test");Toast.makeText(ThreeActivity.this,"来自JS: "+text,Toast.LENGTH_SHORT).show();

js端也是要注册的

//创建一个MyJSModule.js的单独文件'use strict';const BatchedBridge = require('BatchedBridge');const MyJsModule = {    getText(param) {        console.log(param);        return "this is js Module";    }};//要注册啊,大兄弟,这个方法要有的BatchedBridge.registerCallableModule(  'MyJsModule',   MyJsModule);module.exports = MyJsModule;---------------------------------//在index.android.js中还需要引用啊require('./MyJSModule.js');

Android中ReactNative处理流程

应用的启动流程

ReactNative本身是相当灵活的.可支持多种嵌套的方式,真正的启动的应用的时候只需要调用ReactRootView.startApplication即可.

不采用其封装的ReactActivity类,自己来启动ReactNative的过程.

       //重新创建,或者 通过ReactHost来处理        mReactInstanceManager = ReactInstanceManager.builder()                .setApplication(getApplication())                .setBundleAssetName("index.android.bundle")                .setJSMainModuleName("index.android")                .addPackage(new MainReactPackage())                .addPackage(new MyPackage())                .setUseDeveloperSupport(BuildConfig.DEBUG)                .setInitialLifecycleState(LifecycleState.RESUMED)                .build();     //真正的启动,只需要这两步骤,不过由于依赖于ReactInstanceManager,要先实例化它.        mReactRootView = new ReactRootView(this);        mReactRootView.startReactApplication(mReactInstanceManager, "AwesomeProject", null);

其启动过程的有一个大致的示意图.

我是图片啊

以上的最后模块就的调用到了js端的AppRegister.js(该文件位于:/node_modules/react-native/Libraries/ReactNative目录下面)
这里有一点值得说明的,通常是调用react-native run-android的方式来启动应用,不过其应用默认启动MainActivity的类.可以指定启动的Activity,通过命令加参数–main-activity.(该文件位于/node_modules/react-native/local-cli/runAndroid)

//文件中的参数值module.exports = {  name: 'run-android',  description: 'builds your app and starts it on a connected Android emulator or device',  func: runAndroid,  options: [{    command: '--install-debug',  }, {    command: '--root [string]',    description: 'Override the root directory for the android build (which contains the android directory)',    default: '',  }, {    command: '--flavor [string]',    description: '--flavor has been deprecated. Use --variant instead',  }, {    command: '--variant [string]',  }, {    command: '--appFolder [string]',    description: 'Specify a different application folder name for the android source.',    default: 'app',  }, {    command: '--appIdSuffix [string]',    description: 'Specify an applicationIdSuffix to launch after build.',    default: '',  }, {    command: '--main-activity [string]',    description: 'Name of the activity to start',    default: 'MainActivity',  }, {    command: '--deviceId [string]',    description: 'builds your app and starts it on a specific device/simulator with the ' +      'given device id (listed by running "adb devices" on the command line).',  }, {    command: '--no-packager',    description: 'Do not launch packager while building',  }],};

java与js相互调用

调用示意图
1.NativeModule的注册对于程序员来说是透明,只需要集成类加入Package就好了.
2.js端的模块注册需要手动的完成,通过BatchedBrige来完成注册.

源代码编译

好吧,我还没有弄,等下回再弄吧。

原创粉丝点击