1、Native加载Weex页面(js)
WXSDKInstance加载URL
加载本地:
public void render(String template, Map<String, Object> options, String jsonInitData) { render(template, options, jsonInitData, WXRenderStrategy.APPEND_ASYNC); }
加载远程:
public void renderByUrl(String pageName, final String url, Map<String, Object> options, final String jsonInitData, final WXRenderStrategy flag) { renderByUrlInternal(pageName,url,options,jsonInitData,flag); }
2、Weex调用Native。
Weex 提供了扩展机制,可以根据自己的业务进行定制自己的功能。
主要分为三类扩展:
- Module 扩展 非 UI 的特定功能。例如 sendHttp、openURL 等。
- Component 扩展 实现特别功能的 Native 控件。例如:RichTextview,RefreshListview 等。
- Adapter 扩展 Weex 对一些基础功能实现了统一的接口,可实现这些接口来定制自己的业务。例如:图片下载等。
2.1 Module 扩展
- Module 扩展必须继承 WXModule 类。
- 扩展方法必须加上
@JSMethod (uiThread = false or true)
注解。Weex 会根据注解来判断当前方法是否要运行在 UI 线程,和当前方法是否是扩展方法。 - Weex是根据反射来进行调用 Module 扩展方法,所以Module中的扩展方法必须是 public 类型。
- 同样因为是通过反射调用,Module 不能被混淆。请在混淆文件中添加代码:
-keep public class * extends com.taobao.weex.common.WXModule{*;}
- Module 扩展的方法可以使用 int, double, float, String, Map, List 类型的参数
- 完成 Module 后一定要在初始化时注册
WXSDKEngine.registerModule("myModule", MyModule.class);
否则会报类似错误:ReportException :undefined:9: TypeError: Object #<Object> has no method 'printLog'
开发步骤:1)自定义好接收Weex的Module
public class WXEventModule extends WXModule {
@JSMethod()
public void openURL(String url) {
if (TextUtils.isEmpty(url)) {
return;
}
Uri uri = Uri.parse(url);
String scheme = uri.getScheme();
if (scheme.equals("http") || scheme.equals("https") || scheme.equals("file")) {
Intent renderIntent = new Intent(mWXSDKInstance.getContext(), WXPageActivity.class);
renderIntent.setData(uri);
mWXSDKInstance.getContext().startActivity(renderIntent);
} else {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
mWXSDKInstance.getContext().startActivity(intent);
}
}
/**
* 打开购物车
*/
@JSMethod
public void ShoppingCart() {
WXLogUtils.d("WXEventModule", "ShoppingCart");
Toast.makeText(mWXSDKInstance.getContext(), "购物车", Toast.LENGTH_SHORT).show();
}
}
2)注册Module
Application中,注册定义的Module
public class WXApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
WXSDKEngine.addCustomOptions("appName", "WXSample");
WXSDKEngine.addCustomOptions("appGroup", "WXApp");
WXSDKEngine.initialize(this,
new InitConfig.Builder().setImgAdapter(new ImageAdapter()).build()
);
try {
WXSDKEngine.registerModule("navevent", WXEventModule.class);
} catch (WXException e) {
e.printStackTrace();
}
AppConfig.init(this);
WeexPluginContainer.loadAll(this);
}
}
JSMETHOD标识Weex调用的方法。注意注册的时候,名称一定要和服务器定义的一致。
3)Weex怎么调用Native定义的Module方法呢?
weex.requireModule("navevent").ShoppingCart();
2.2 Component 扩展
- Component 扩展类必须继承 WXComponent.
- Component 对应的设置属性的方法必须添加注解 @WXComponentProp(name=value(value is attr or style of dsl))
- Weex sdk 通过反射调用对应的方法,所以 Component 对应的属性方法必须是 public,并且不能被混淆。请在混淆文件中添加代码
-keep public class * extends com.taobao.weex.ui.component.WXComponent{*;}
- Component 扩展的方法可以使用 int, double, float, String, Map, List 类型的参数
- 完成 Component 后一定要在初始化时注册
WXSDKEngine.registerComponent("richText", RichText.class);
1)定义Component组件
public class RichText extends WXComponent<TextView> {
public RichText(WXSDKInstance instance, WXDomObject dom, WXVContainer parent) {
super(instance, dom, parent);
}
@Override
protected TextView initComponentHostView(@NonNull Context context) {
TextView textView = new TextView(context);
textView.setTextSize(20);
textView.setTextColor(Color.BLACK);
return textView;
}
@WXComponentProp(name = "tel")
public void setTel(String telNumber) {
getHostView().setText("tel: " + telNumber);
}
}
2)注册Component组件
WXSDKEngine.registerComponent("richText", RichText.class);
3)Weex调用Native定义的组件
<template>
<div>
<richText tel="12305" style="width:200;height:100">12305</richText>
</div>
</template>
当然组件也可以定义JSMethod。
2.3 Adapter扩展
public class ImageAdapter implements IWXImgLoaderAdapter {
public ImageAdapter() {
}
@Override
public void setImage(final String url, final ImageView view,
WXImageQuality quality, WXImageStrategy strategy) {
WXSDKManager.getInstance().postOnUiThread(new Runnable() {
@Override
public void run() {
if(view==null||view.getLayoutParams()==null){
return;
}
if (TextUtils.isEmpty(url)) {
view.setImageBitmap(null);
return;
}
String temp = url;
if (url.startsWith("//")) {
temp = "http:" + url;
}
if (view.getLayoutParams().width <= 0 || view.getLayoutParams().height <= 0) {
return;
}
Picasso.with(WXEnvironment.getApplication())
.load(temp)
.into(view);
}
},0);
}
}
2)WXSDKEngine初始化的时候设置适配器。
WXSDKEngine.addCustomOptions("appName", "WXSample");
WXSDKEngine.addCustomOptions("appGroup", "WXApp");
WXSDKEngine.initialize(this,
new InitConfig.Builder().setImgAdapter(new ImageAdapter()).build()
);
3. Native调用Weex
Native回调JS,通过WXSDKInstance的fireGlobalEventCallback回调JS方法。
/*Global Event*/
private HashMap<String, List<String>> mGlobalEvents = new HashMap<>();
public void fireGlobalEventCallback(String eventName, Map<String,Object> params){
List<String> callbacks=mGlobalEvents.get(eventName);
if(callbacks!=null){
for(String callback:callbacks){
WXSDKManager.getInstance().callback(mInstanceId,callback,params,true);
}
}
}
最终通过WXBridge执行JS方法回调处理。
/**
* Execute JavaScript function
*
* @param instanceId
* @param namespace default global
* @param function function string name
* @param args WXJSObject array
*/
public native int execJS(String instanceId, String namespace, String function, WXJSObject[] args);
参考文献:
http://weex.apache.org/cn/guide/extend-android.html