Weex-Android 教程-从入门到放弃

image

序言

我所在的公司是一家外包公司,项目很多可是只有我一位Android开发,为了能更有效率的接项目,经理决定让有Vue基础的几位前端开发配合我开发,于是就有了一篇踩坑的文章。

1.Weex是个啥?

Weex是阿里巴巴出品的一套类似React Native的混合开发技术,目标是一套代码,多端运行。(Web,IOS,Android)阿里自家的淘宝客户端上也有使用。能通过加载服务器js文件随时切换UI。

2.咋样用?

1.配置环境

在Android端的配置并不复杂,按教程设置gradle依赖,权限,然后在你的Application初始化

  fun initWeexSdk() {
        val config = InitConfig.Builder().build()
        WXSDKEngine.initialize(this, config)
    }

跟教程比少了两个Adapter,但是没关系,后面会讲到怎么用。
接下来就要封装一个简单的BaseWXActivity,继承IWXRenderListener

abstract class BaseWXActivity : BaseActivity(), IWXRenderListener {

    var mWXSDKInstance: WXSDKInstance? = null

    fun render(pageName: String, path: String) {
        mWXSDKInstance?.isTrackComponent = true
        mWXSDKInstance?.render(
            pageName,
            WXFileUtils.loadAsset(path, this@BaseWXActivity),
            null,
            null,
            WXRenderStrategy.APPEND_ASYNC
        )
    }

    protected fun renderPage(path: String) {
        initSetting()
        renderPage(path, null)
        log("render - $path")
    }

    fun initSetting() {
        mWXSDKInstance = WXSDKInstance(this)
        mWXSDKInstance?.registerRenderListener(this)
    }

    override fun onRefreshSuccess(instance: WXSDKInstance?, width: Int, height: Int) {
        log("onRefreshSuccess")
    }

    override fun onException(instance: WXSDKInstance?, errCode: String?, msg: String?) {
        log("onException$msg")
    }

    override fun onViewCreated(instance: WXSDKInstance?, view: View?) {
        log("onRenderSuccess")
    }

    override fun onRenderSuccess(instance: WXSDKInstance?, width: Int, height: Int) {
        log("onRenderSuccess")
    }

    override fun onResume() {
        super.onResume()
        mWXSDKInstance?.onActivityResume()
    }

    override fun onPause() {
        super.onPause()
        mWXSDKInstance?.onActivityPause()
    }

    override fun onStop() {
        super.onStop()
        mWXSDKInstance?.onActivityStop()
    }

    override fun onDestroy() {
        super.onDestroy()
        mWXSDKInstance?.onActivityDestroy()
    }

}

mWXSDKInstance?.registerRenderListener(this)是注册方法
而mWXSDKInstance?.render 则是调用界面的方法,因为我的项目都是导入本地的js文件,所以这里path用了 WXFileUtils.loadAsset

要使用Weex的Activity继承BaseWXActivity,在onCreate中调用initSetting,这样就简单的集成好环境开始正式使用了。

重点

当调用了render方法后,如果创建Weex界面成功,会回调onViewCreated这个方法,这个view就是我们的weex的界面了,你应该在将这个view显示在你的布局里,比如最简单的

 override fun onViewCreated(instance: WXSDKInstance?, view: View?) {
    setContentView(R.layout.activity_main)
    }

2.使用

向你的前端小伙伴要一份资源文件,或者拉下他们的代码

image.png

weex项目的目录大概长这样,dist就是我们要使用的资源文件了
将里面的文件拉到android 的 assets 文件夹里

image.png

就可以尝试在你的Activity里启动weex页面啦

image.png

直接使用
renderPage("***.js")
就能看到要加载的页面了

3.原生咋跟Weex交互捏?

weex提供了三种工具让我们交互

Adapter:  图片,网络等加载相关
Moudle: 交互方法
Component: 组件

1.Adapter

weex不支持直接加载res里面的图片,于是需要一个图片的Adapter让weex可以读取到res资源,以下一个简单示例

class ImageAdapter : IWXImgLoaderAdapter{

    override fun setImage(url: String?, view: ImageView?, quality: WXImageQuality?, strategy: WXImageStrategy?) {
        if (url == null){
            return
        }
        log("setImgageg$url")
        val mUrl = url.replace("-","_").toLowerCase()

        val context = MyApplication.mContext!!
        val res = context.resources

        val i = res.getIdentifier(mUrl.replace("/",""), "drawable", context.packageName)
        if (i != 0){
            view?.setImageResource(i)
            strategy?.imageListener?.onImageFinish(url, view, true, null)
        }
    }

}

继承IWXImgLoaderAdapter,重写setImage方法,url即是请求的图片地址,为了兼容IOS这里做了点处理,设置view的资源,调用
strategy?.imageListener?.onImageFinish(url, view, true, null)
即可显示资源图片了,当然这里也可以使用Glide Pacasio 等图片缓存框架。
记得实现ImageAdapter 后需要给它注册一下。 initWeexSdk 方法就变成了

fun initWeexSdk() {
        val config = InitConfig.Builder()
        .setImgAdapter(ImageAdapter())
        .build()
        WXSDKEngine.initialize(this, config)
    }

除了setImgAdapter,还有setHttpAdapter等Adapter,使用上也大同小异。

2.Moudle

Moudle可以理解为Weex跟原生交互的接口模块

首先应该跟你的前端伙伴定一下Api比如

image.png

然后创建一个ApiMoudle 继承WXModule 实现相关方法

class ApiMoudle : WXModule(),{

    @JSMethod(uiThread = false)
    fun getLanguage(callback: JSCallback){
    var language = "en"
       callback.invoke(language )
    }

}

在Android 端的callback叫 JSCallback ,在IOS端叫WXMoudleCallback
调用JSCallback.invoke()即可将值回传到Weex端

完成ApiModule后再注册一下,我们的initWeexSdk就变成

   fun initWeexSdk() {
        val config = InitConfig.Builder()
        .setImgAdapter(ImageAdapter())
           .build()
        WXSDKEngine.initialize(this, config)
        WXSDKEngine.registerModule("swifter", ApiMoudle::class.java)
    }

当Weex端调用getLanguage方法,即可通过callback回调拿到我们传进去的值了

3.Component

Weex的组件有时候不一定能满足实际需求,Component就用于引入原生的控件,比如说实现一个原生的折线图
首先要前端定义一下


image.png

lineChartView 就是我们的 Component名,data就是回传给我们的JSon数据
定义一个Component继承WXComponent<VIEW>

class LineChartComponent : WXComponent<LineChart>{

    lateinit var lineChart: LineChart

    @WXComponentProp(name = "data")
    fun setData(source: String) {

    }

 override fun initComponentHostView(context: Context): LineChart {
        lineChart = LineChart(context)
        return lineChart
    }

}

通过WXComponentProp获取传到原生的属性
重写initComponentHostView返回View
接着写完Component后再注册一下即可正常显示我们的View了

   fun initWeexSdk() {
        val config = InitConfig.Builder().setImgAdapter(ImageAdapter())
            .build()
        WXSDKEngine.initialize(this, config)
        WXSDKEngine.registerModule("swifter", ApiMoudle::class.java)
        WXSDKEngine.registerComponent("lineChartView", LineChartComponent::class.java)
    }

4.听上去还蛮不错,为啥标题叫入门到放弃捏?

先说结论 小型公司不建议使用Weex作为商用项目
这里特指Android端

1.文档很敷衍

最基本的render的使用,callback的使用都一笔带过,想靠短短两页文档掌握Weex是不可能的,最终还要参考博客和实例。

2.性能

不得不说IOS端Weex的体验还是挺顺滑的,可是到了Android端就不一样了,加载页面时会有可观测的卡顿,一开始使用一个WXActivity多个fragment + 多个weex的形式卡顿特别明显,后来将weex放到fragment 使用一个普通Activity加多个WXFragment才稍微好点。如果你的App也是通过侧边栏切换多个fragment的,不建议用Weex。


image.png

我觉得仅仅因为这两点就不建议没有技术深度的小公司使用了。

5.如果我偏要用,有什么躲坑的小经验?

1.用return替代callback

文档都是使用callback来传数据的,但是实际上有些时候需要同步的返回数据,IOS端可以强制callback同步,但是android端没有这个方法,看了下示例才发现原来可以通过直接return的方式返回值。

class ApiMoudle : WXModule(),{

    @JSMethod(uiThread = false)
    fun getLanguage():String{
    return "en"
    }

}

2.关于跳转页面

如果你有Weex跳转界面的需求,你会发现在IOS端可以正常跳转,但是Android不生效(没错,IOS才是亲儿子)
方法1:按照教程配置manifest相关
方法2:(推荐)在Moudle中实现一个跳转方法,当weex调用该方法后,原生通过render跳转。

6.有啥补充?

Weex使用起来其实还是比较简单的,但是文档欠缺,坑也有很多。要弄懂它需要花费点时间,见仁见智吧

参考资料
Weex文档
Weex同步问题

点这里有更多有深度的开发知识

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,324评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,356评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,328评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,147评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,160评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,115评论 1 296
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,025评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,867评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,307评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,528评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,688评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,409评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,001评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,657评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,811评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,685评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,573评论 2 353

推荐阅读更多精彩内容