Weex中Activity间传递数据

1,032 阅读2分钟

在用weex做应用开发的时候可能很多时候我们需要开启另一个Activity并传些数据给他,但是貌似weex本身没有提供这样一个机制来做这个事情,我找遍了weex所有的文档也没找到相关的说明...我在想,这不应该是一个基础的东西吗?

好吧接下来我将用尽量概括的文字描述如何实现

首先我们要做的事情是:
1.js作为发起者,要告诉原生打开另一个Activity,而且要告诉原生要打开的另一个Activity的url,和参数
2.原生接到方法调用以后打开新的Activity并把新的url和参数通过intent传过去
3.新的Activity被开启以后从Intent里取出数据,打开相关的url并且将参数保存下来,等js需要的时候让js拿走。

↓↓↓ 所以大体上我们需要实现以下方法

/**
 * js调用Native 告诉原生打开另一个Activity,url是新页面的地址,json是参数,json格式
 */
public void openNewWeexPage(String url,String json);

/**
 * js调用Native 来获取上个页面传过来的json.
 * 为什么要选择js调用安卓是因为Native并不知道该在什么时候调js层,所以在js调比较稳妥.
 */
public String getInitData();

OK,现在的问题是,这些方法写在哪?

weex实现了一套js与Native交互的机制,比如说可以进行自定义Module。但是自定义Module有个问题是,它只能注册class而不能注册实例,也就是说你在js层获取到的Module是SDK自动生成的,是与Activity不相干的,我们也不能吧Activity当成Module来运行...

好在翻了翻源码之后还是找到了解决方法:Module里包含WXSDKInstance的引用,js调原生方法也是通过Module里的WXSDKInstance进行的(过程很复杂不赘述),然后我们直到WXSDKInstance这东西是我们在Activity里自己生成的,所以这就好办了

//IWeexActivity.java
/**
 * 定义一个通信接口,来对Activity进行操作
 */
public interface IWeexActivity {
    String getInitData();
}

//NavigateModule.java
/**
 * description:
 * Created by WJD on 2018/4/27.
 */
public class NavigateModule extends WXModule{

    /**
     * this method must be declared as non-ui thread as js might not receive result if you don't.
     */
    @JSMethod(uiThread = false)
    public String getInitData(){
        String data = null;
        Context context = mWXSDKInstance.getContext();
        if (context instanceof IWeexActivity){
            data = ((IWeexActivity) context).getInitData();
        }
        return data;
    }

    @JSMethod(uiThread = true)
    public void openNewWeexPage(String url,String data){
        Context context = mWXSDKInstance.getContext();
        Intent intent = new Intent(context, WeexActivity.class);
        intent.putExtra("url",url);
        intent.putExtra("extra",data);
        context.startActivity(intent);
    }
}

//WeexActivity.java
public class SinglePageActivity extends WXBaseActivity implements IWeexActivity {
    private WXSDKInstance wxInstance;
    private String url,extraData;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        url = getIntent().getStringExtra("url");
        extraData = getIntent().getStringExtra("extra");
        wxInstance = new WXSDKInstance(this);
        ...
    }
    
    @Override
    public String getInitData() {
        return extraData;
    }
}

//BaseApplication.java
WXSDKEngine.registerModule("NavigateModule", NavigateModule.class);

//page1.vue
var navigate = weex.requireModule('NavigateModule');
onSomthingHappen(){
    navigate.openNewWeexPage(newUrl,"this is data of json format.");
}

//page2.vue
var navigate = weex.requireModule('NavigateModule');
created(){
    var initData = navigate.getInitData();
}

完成