React-Native 学习笔记

各类学习资源参见:http://www.tuicool.com/articles/zaInUbA

要使java的接口能被javascript调用,主要有三个步骤:

步骤一:编写接口类,在类中编写对应的、供javascript调用的接口。

步骤二:编写接口对应的包类,在类中将步骤一编写的接口类添加到此包中。

步骤三:MainActivity类,在此类中,添加步骤二中编写的包类。

完成以上三步,javascript就能调用java的接口了。


一、接口类

假设编写一个名为ReadIDModule 的接口类,参考代码如下:

package com.nativetest;

import android.widget.Toast;

import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.Arguments;

import java.util.HashMap;
import java.util.Map;

public class ReadIDModule extends ReactContextBaseJavaModule {

<span style="white-space:pre">	</span>private static final String DURATION_SHORT_KEY = "SHORT";
<span style="white-space:pre">	</span>private static final String DURATION_LONG_KEY = "LONG";

<span style="white-space:pre">	</span>public ReadIDModule(ReactApplicationContext reactContext){
<span style="white-space:pre">		</span>super(reactContext);
	}
	
	@Override
	public String getName() {
		return "ReadIDModule";
	}
	
    <span style="white-space:pre">	</span>@Override
    <span style="white-space:pre">	</span>public Map<String, Object> getConstants() {
        <span style="white-space:pre">	</span>final Map<String, Object> constants = new HashMap<>();
        <span style="white-space:pre">	</span>constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
        <span style="white-space:pre">	</span>constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
        <span style="white-space:pre">	</span>return constants;
    <span style="white-space:pre">	</span>}
	
	@ReactMethod
	public void getIdCardInfo(Callback infoCallback) {
	
		// 读二代证代码,此处省略
		// 假设所读信息存放在自定义类IdCardInfo的对象idCardInfo中,并以Map传给javascript
		WritableMap map = Arguments.createMap();
	    <span style="white-space:pre">	</span>map.putString("cardId", new String(perInfo.cardId).trim());
	    <span style="white-space:pre">	</span>map.putString("name", new String(perInfo.name).trim());
	    <span style="white-space:pre">	</span>map.putString("sex", new String(perInfo.sex).trim());
	    <span style="white-space:pre">	</span>map.putString("nation", new String(perInfo.nation).trim());
	    <span style="white-space:pre">	</span>map.putString("birthday", new String(perInfo.birthday).trim());
	    <span style="white-space:pre">	</span>map.putString("address", new String(perInfo.address).trim());
	    <span style="white-space:pre">	</span>map.putString("police", new String(perInfo.police).trim());
	    <span style="white-space:pre">	</span>map.putString("validStart", new String(perInfo.validStart).trim());
	    <span style="white-space:pre">	</span>map.putString("validEnd", new String(perInfo.validEnd).trim());
		
		infoCallback.invoke(map);
	}

	@ReactMethod
	public void showToast(String message, int duration){
		Toast.makeText(getReactApplicationContext(), message, duration).show();
	}
	
	@ReactMethod
	public void getCusName(Callback nickNameCallback){
		nickNameCallback.invoke(new String(perInfo.name).trim);
	}
}



说明:

此处主要介绍javascript如何给java参数,java如何返回信息给javascript。

1.@Override的getName()方法很重要,指明了javascript中此模块的名称。

2.@Override的getConstants()方法指明了javascript可用的在java中定义的常数,如没有可不重写此方法。

3.以@ReactMethod标明的方法就是提供给javascript的接口。

4.javascript向java的接口传递参数,可传递的类型及映射到javascript的类型如下:

java javascript

Boolean -> Bool
Integer -> Number
Double -> Number
Float -> Number
String -> String
Callback -> function
ReadableMap -> Object
ReadableArray-> Array

5.java返回数据给javascript没法直接用return的方式返回,需要调用回调函数,向回调函数传递参数的方式来实现。回调函数就是接口中Callback类型的入参。

一个接口可有多个回调函数,但一个回调函数只能传递一个参数,回调函数可传递的类型及映射到javascript的类型如下:

java javascript

Boolean -> Bool
Integer ->  Number
Double  -> Number
Float  ->  Number
String  ->  String
WritableMap ->  Object
WritableArray->  Array

6.实例化一个WritableMap不是用new,而是用Arguments.createMap()。

WritableMap源码如下:

package com.facebook.react.bridge;

/**
 * Interface for a mutable map. Used to pass arguments from Java to JS.
 */
public interface WritableMap extends ReadableMap {

  void putNull(String key);
  void putBoolean(String key, boolean value);
  void putDouble(String key, double value);
  void putInt(String key, int value);
  void putString(String key, String value);
  void putArray(String key, WritableArray value);
  void putMap(String key, WritableMap value);

  void merge(ReadableMap source);
}


ReadableMap则是getBoolean(String key)、getString(String key)等。

7.实例化一个WritebleArray也是一样,用Arguments.createArray)。

WritebleArray源码如下:

package com.facebook.react.bridge;

/**
 * Interface for a mutable array. Used to pass arguments from Java to JS.
 */
public interface WritableArray extends ReadableArray {

  void pushNull();
  void pushBoolean(boolean value);
  void pushDouble(double value);
  void pushInt(int value);
  void pushString(String value);
  void pushArray(WritableArray array);
  void pushMap(WritableMap map);
}


二、接口包类

假设编写一个名为ReadIDModule 的接口包类,参考代码如下:

package com.nativetest;

import com.facebook.react.ReactPackage; 
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import java.util.ArrayList; 
import java.util.List;
import java.util.Arrays;
import java.util.Collections;

public class ReadCardPackage implements ReactPackage {
	/*
	注册模块#
	我们需要在你的应用的Package类的createNativeModules方法中添加这个模块。
	如果一个模块没有被注册,它从JavaScript中也无法访问到。
	*/
  	@Override
	public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
	    List<NativeModule> modules = new ArrayList<>();

	   <span style="color:#ff0000;"> </span><span style="background-color: rgb(204, 0, 0);">modules.add(new ReadIDModule(reactContext));</span>

	    return modules;
	  }
	@Override
	public  List<Class<? extends JavaScriptModule>> createJSModules(){
		return Collections.emptyList();
	}
	@Override
	public  List<ViewManager> createViewManagers(ReactApplicationContext reactContext){
		return Arrays.asList();
	}

}

重点看红色字体部分,其余均无需改变。如有多个接口类都要归到这个包,只需往modules再add一个即可,add进去的为借口类的对象。


三、主程序MainActivity

package com.nativetest;

import com.facebook.react.ReactActivity;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.react.shell.ReactMaterialKitPackage;

import java.util.Arrays;
import java.util.List;

public class MainActivity extends ReactActivity {

	private LogcatUtil logcat;
	private static AutofillSettings conf;
	private static Context context;
	
    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {		
        <span style="background-color: rgb(204, 0, 0);">return "NativeTest";</span>
    }

    /**
     * Returns whether dev mode should be enabled.
     * This enables e.g. the dev menu.
     */
    @Override
    protected boolean getUseDeveloperSupport() {
        return BuildConfig.DEBUG;
    }

   /**
   * A list of packages used by the app. If the app uses additional views
   * or modules besides the default ones, add more packages here.
   */
    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
        new MainReactPackage(),
	<span style="background-color: rgb(255, 0, 0);">new ReadCardPackage()</span>
      );
    }
}

红色字体部分为重点,return "NativeTest"表示主要组件的名称,通常是工程名。new ReadCardPackage()表示将此接口包添加到主要组件中,如有多个接口包,可再此添加接口包。




如图,MainActivity可添加多个包类,每个包类又可添加多个接口类。有助于代码的分类管理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值