让 Android 开发像 web 开发一样爽

作者:hanks https://juejin.im/post/5bf12c8751882511a8527ed4

做移动端开发,最蛋疼的就是不能动态发版,不能像 web 那样发版立即全部用户生效,然而 lua语言 为其提供了可能性。lua 是一种脚本语言,使用 lua 来构建跨平台原生应用有许多好处,比如 lua 语言简洁高效,可移植性好, Lua虚拟机极为轻量,仅占用200到300k的内存空间,且速度极快。

演示

写一个简单的代码演示一下。新建一个 lua 文件,叫做 view.lua, 放在手机的 sdcard 上,文件目录为 /sdcard/view.lua

require "import"
import "android.widget.*"
import "android.content.*"

function getView()
    local layout = {
        LinearLayout,
        orientation = "vertical",
        layout_width = "fill",
        layout_height = "fill",
        {
            Button,
            id = "btn",
            layout_marginTop="8dp",
            layout_width = "fill",
            layout_height = "50dp",
            text = "click"
        },
    }
    local view = loadlayout(layout)
    return view
end

运行一下,

屏幕中上半部分是 Android 的 xml 布局中写好的代码,当点击运行按钮时,加载 lua 脚本,返回一个 View 对象,然后添加到布局中。一个简单的 lua 脚本编写的视图就写好了。 接下来修改一下,设置个点击事件。

require "import"
import "android.widget.*"
import "android.content.*"

function getView()
    local layout = {
        LinearLayout,
        orientation = "vertical",
        layout_width = "fill",
        layout_height = "fill",
        {
            Button,
            id = "btn",
            layout_marginTop="8dp",
            layout_width = "fill",
            layout_height = "50dp",
            text = "click"
        },
    }
    local ids = {} -- store ids to find view
    local view = loadlayout(layout, ids)
    ids.btn.onClick = function()
        Toast.makeText(activity,"2333",0).show()
    end
    return view
end

运行效果

再来个稍微复杂点的例子,写个列表,新建 list.lua 文件,放在手机的 sdcard/list.lua

require "import"
import "android.widget.*"
import "android.content.*"
import "android.view.View"
import "androlua.LuaHttp"
import "androlua.LuaAdapter"
import "androlua.LuaImageLoader"

local JSON = require("cjson")
local uihelper = require('uihelper')

-- create view table
local layout = {
    LinearLayout,
    orientation = "vertical",
    layout_width = "fill",
    layout_height = "fill",
    {
        ListView,
        id = "listview",
        dividerHeight = 0,
        layout_width = "fill",
        layout_height = "fill",
    },
}

local item_view = {
    FrameLayout,
    layout_width = "fill",
    layout_height = "240dp",
    {
        ImageView,
        id = "iv_image",
        layout_width = "fill",
        layout_height = "fill",
        scaleType = "centerCrop",
    },
    {
        TextView,
        id = "tv_title",
        background = "#66000000",
        layout_width = "fill",
        layout_height = "fill",
        padding = "32dp",
        gravity = "center",
        maxLines = "5",
        lineSpacingMultiplier = '1.2',
        textSize = "14sp",
        textColor = "#CCFFFFFF",
    },
}


local data = {
    dailyList = {}
}
local adapter

local function getData()
    -- http://baobab.kaiyanapp.com/api/v1/feed
    local url = data.nextPageUrl
    if url == nil then url = 'http://baobab.kaiyanapp.com/api/v1/feed?udid=3e7ee30c6fc0004a773dc33b0597b5732b145c04' end
    if url:find('udid=') == nil then url = url .. '&udid=3e7ee30c6fc0004a773dc33b0597b5732b145c04' end
    print(url)
    LuaHttp.request({ url = url }, function(error, code, body)
        if error or code ~= 200 then
            print('fetch data error')
            return
        end
        local str = JSON.decode(body)
        uihelper.runOnUiThread(activity, function()
            data.nextPageUrl = str.nextPageUrl
            local list = str.dailyList[1].videoList
            for i = 1, #list do
                data.dailyList[#data.dailyList + 1] = list[i]
            end
            adapter.notifyDataSetChanged()
        end)
    end)
end

local function launchDetail(item)
    Toast.makeText(activity, item.title, 0).show()
end

function getView()
    local view = loadlayout(layout)
    adapter = LuaAdapter(luajava.createProxy("androlua.LuaAdapter$AdapterCreator", {
        getCount = function() return #data.dailyList end,
        getItem = function(position) return nil end,
        getItemId = function(position) return position end,
        getView = function(position, convertView, parent)
            position = position + 1 -- lua 索引从 1开始
            if position == #data.dailyList then
                getData()
            end
            if convertView == nil then
                local views = {} -- store views
                convertView = loadlayout(item_view, views, ListView)
                if parent then
                    local params = convertView.getLayoutParams()
                    params.width = parent.getWidth()
                end
                convertView.setTag(views)
            end
            local views = convertView.getTag()
            local item = data.dailyList[position]
            if item then
                LuaImageLoader.load(views.iv_image, item.coverForFeed)
                views.tv_title.setText(item.title)
            end
            return convertView
        end
    }))
    listview.setAdapter(adapter)
    listview.setOnItemClickListener(luajava.createProxy("android.widget.AdapterView$OnItemClickListener", {
        onItemClick = function(adapter, view, position, id)
            launchDetail(data.dailyList[position + 1])
        end,
    }))
    getData()
    return view
end

复制代码创建 listView , 设置 adapter ,网络请求,刷新列表。看下效果吧。

代码放到了 github

:https://github.com/hanks-zyh/luaDevAndroid

原理图

写了几篇文章比较详细的介绍了原理,想了解的可以看一下

Android 与 Lua 探究 lua 在 Android 中的应用 Lua 嵌入 Android 原理

支持 iOS 吗?

Lua 是用 c 语言开发的,可移植性比较好,想支持 iOS 的话,原理时一样的,不过参考目前已有的跨平台技术。关于跨平台方面的一些个人见解,目前已有的跨平台技术每当涉及到不同平台的特性时,事情就比较蛋疼了,需要单独去适配,还有建立一堆连接库,比如选取本地图片,不同平台的数据库,平台特有 api,真是一份代码到处运行终是梦,一份儿代码到处采坑才是真。

Android 开发能支持到什么程度?

看到了上面的原理图就可以知道,支持 Android SDK 几乎所有的 API。

— — — END — — —

原文发布于微信公众号 - 刘望舒(liuwangshuAndroid)

原文发表时间:2018-11-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏分享达人秀

引入Fragment原来是这么回事

随着大众生活水平的提高,再加上移动互联网的迅速发展,几乎每个人都至少拥有一台搭载Android系统的移动设备。Android设备的多样性给我们带来了很大...

37650
来自专栏非著名程序员

浅谈Andorid开发中的MVP模式

? 导语:最近公众号后台经常收到一些消息,说能不能讲一些开发模式,经过思考后,我决定讲一讲MVP模式。希望对大家能够有所帮助。并写了一个简单的小demo。 ...

24060
来自专栏Android开发指南

Android MVP理解

36760
来自专栏郭霖

Android提醒微技巧,你真的了解Dialog、Toast和Snackbar吗?

今天给大家带来一篇简单易懂的微技巧文章,并没有什么高深的技术点,但重点仍然是在细节,相信还是可以给不少朋友带来帮助的。 Dialog和Toast所有人肯定都不会...

22880
来自专栏Android干货

Android项目实战(三十四):蓝牙4.0 BLE 多设备连接

1.1K60
来自专栏非著名程序员

Base封装之我的最简MVP架构

绪论 最近懒癌症犯了,好久都没写博客了,当然也在做一些东西,也在整理自己一直以来使用的一些技术点,从Retrofit到OkGO,从ListView到Recycl...

33990
来自专栏小鄧子的技术博客专栏

【译】Android技术栈,1#架构

本文是如何开发一款具有扩展性,维护性和测试性的Android应用专题的第一篇。本专题将会涉及到一些设计模式和类库的使用方式,减少Android Develope...

11430
来自专栏腾讯Bugly的专栏

Android APP 快速 Pad 化实现

如何能在最快的时间内,实现一个最新版本 Android app 的 pad 化呢?从拿到一个大型手机 app 代码开始开发到第一个其全新 pad 版本的发布,我...

65060
来自专栏极客猴

Android设计模式之MVP

最近利用业余时间来深入学习MVP模式,我把自己对MVP模式的理解分享给大家,希望能给你理解MVP模式提供帮助。

12810
来自专栏Android干货园

Base封装(一)--我的最简MVP架构

版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/lyhhj/article/details/73...

16010

扫码关注云+社区

领取腾讯云代金券