美文网首页
LuaViewSDK 简单入坑

LuaViewSDK 简单入坑

作者: 土肥圆的诺诺 | 来源:发表于2020-02-28 22:49 被阅读0次

入坑的的原因是大佬想解决动态下发问题,当初觉得这个SDK能解决问题,就派我去调研这个东西...然而调研总是要出一些东西产出的,当时我查了下,全网写关于这个SDK的文章真的非常少,所以就有了这篇文章。先把基友网地址发出来:https://alibaba.github.io/LuaViewSDK/guide.html
我个人认为 这玩意就是为了解决动态下发的问题,然后封装了各端代码,最起码我们是用来解决动态下发问题的。

首先,简单介绍下,LuaViewSDK入门难么?答案不难。有点经验的开发人员,入门2天吧,第一天看看lua的基本语法,第二天对着api挨个实验就行了。然而...我真的不建议大家使用这个。因为在2020年的今天,这个项目已经好几年没维护了。Latest commit on 14 Aug 2017。项目现在没人维护,不过当初用在聚划算项目上,也算我辈膜拜的程度。

简单说下我入坑的过程,第一天 我了解下啥是lua,装lua环境,毕竟不会就虚的很。第二天觉得自己差不多掌握了基本语法,开始往AS倒SDK包(这里我踩坑了,报错很多,毕竟三年的项目了,如果项目使用的androidX更麻烦)。第三天,我各种踩坑,但是能基本写点东西了。基本就这样子,接下来,我按照我当初的步骤一步步写出来。

windows安装环境请自行百度(虽然我在家也是windows,心疼下我为写代码买的主机)。我将在mac端一步步自己重新开始,再写出来。

1 先到官网 http://www.lua.org/download.html

image.png

点击下载,然后随便自己建个文件夹扔进去。(下面是我复制别人的,但是我实验了好用)

解压之后,命令行cd进入到src目录下,输入make macosx

完成后cd ..到上一层目录, 输入sudo make install

然后 输入 lua,显示出版本号,这就成功了。

image.png

接下来编辑器问题,我本来想用subLime,但是本渣渣灰一直把这神器当文本文档用。
这里有个插件叫EmmyLua,我在windows上就用的这个 贼好使
我在mac上继续沿用。打开AS,然后点击左上角Mac图标右边的Android Studio按钮,在弹出的功能选项中点击Preferences,找到Plugins,然后输入EmmyLua,install,然后重启ok。
然后, 新建assets文件夹,在assets 上,右键,新建,new Lua File ,写下下面的代码,右键run xx.lua,然后下面就出来了hello wordl。

local  name ="hello wordl"
print(name)

到这里我感慨了下,还是mac牛逼,我在windows上还得配下sdk环境,这都不用直接就能跑了 - -!
如果你安装出啥问题了,就度娘下,windows怎么装的我忘记了,反正最好还得配置下sdk路径,我用mac居然不用了,感觉美滋滋。
接下来是lua的简单语法,大神直接略过。也可看菜鸟窝相关的东西,(https://www.runoob.com/lua/lua-tutorial.html),我第一天看的不是特别懂,我还特地找了本书(Lua程序设计随便给个下载地址 http://www.downcc.com/soft/313218.html )。看了一晚上,然后我就学会了最基本的语法,比如for 循环啊,table啊,因为LuaViewSDK并非纯lua,所以不用那么学特别多。其实真当你使用sdk的时候发现最常用的就是 local 和冒号(调用方法) 。
接下来下载导入LuaViewSDK,下载地址:https://github.com/alibaba/LuaViewSDK,直接downLoad。因为我是搞android的,IOS我就不管了。down的时候,可以先去建个新的项目,一会用来练手。
下载下来,熟练解压,LuaViewSDK-master 中Android文件夹下的LuaViewSDK,这下面才是我们要用的东西。别运行那个demo了,反正我没运行起来。我们不是新建了个项目么。
File -New -import Model ,将那个导入到项目
倒完包,发现运行不起来了,这是正常的,淡定淡定。根据报错,挨个排查。

//找到LuaViewSDK的AndroidManifest文件  将minSdkVersion 删除掉
<uses-sdk android:minSdkVersion="14" />

这是我改的LuaViewSDK的build.gradle

apply plugin: 'com.android.library'

description = """LuaView-Android: 用lua写Android、iOS"""

repositories {
    mavenLocal()
    mavenCentral()
    jcenter()
}

configurations {
    providedCompile
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:support-v4:23.0.1'
    //recycler view
    implementation 'com.android.support:recyclerview-v7:23.0.1'
//    compile 'com.android.support:appcompat-v7:23.4.0'
}

/*
  定义android插件
*/
android {
    compileSdkVersion 23
    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src', 'src-csslayout']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

  
        debug.setRoot('build-types/debug')
        release.setRoot('build-types/release')
    }
    packagingOptions {
        exclude 'META-INF/LICENSE.txt'
    }
    buildTypes {
        debug {
            debuggable true
        }
    }
    lintOptions {
        abortOnError false
    }
}


因为新建的项目一般版本比较高默认使用androidX,可以将版本向下压制一下,

如果不想使用androidX 可以将gradle.properties 下面属性改为false

android.useAndroidX=false
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=false

这是我项目app下的build.gradle配置

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"
    defaultConfig {
        applicationId "com.leo.luademotest"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    implementation 'com.android.support:support-v4:23.0.1'
    //recycler view
    implementation 'com.android.support:recyclerview-v7:23.0.1'
//    androidTestImplementation 'androidx.test:runner:1.2.0'
//    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    implementation project(':LuaViewSDK')

}

现在如果编译还有什么错,那就按照报错提示修改,可能buildtools版本不一样,修改下就可以了。现在我这里是可以跑起来了。接下来看LuaViewSDK相关的东西。

首先先拉平一个概念,就是LuaView 你就把他当成一个Andeoid中的View去用就行。这样理解比较简单。
LuaVIew创建的方式

//直接创建
            LuaView luaView= LuaView.create(getContext());
            //异步创建
        LuaView async = LuaView.createAsync(getContext());
            // 异步创建 带回调监听 推荐第三种
        LuaView.createAsync(getContext(), new LuaView.CreatedCallback() {
            @Override
            public void onCreated(LuaView luaView) {
                
            }
        });


LuaViewConfig 配置(按需设置)

LuaViewConfig.init(this);//初始化,只需要调用一次
LuaViewConfig.setDebug(true);//设置是否debug,默认release模式下不会开启
LuaViewConfig.setOpenDebugger(false);//是否开启调试器,默认模拟器环境会开启,真机不会开启。TODO Android 真机调试
LuaViewConfig.setAutoSetupClickEffects(true);//是否自动设置点击效果(如果有点击事件会自动设置)...

加载本地lua文件
在assets下创建xxx.lua文件,点击运行就在页面上看到一个按钮。

public class MainActivity extends Activity {

    private LinearLayout llContent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        llContent = findViewById(R.id.ll_content);

        LuaView.createAsync(this, new LuaView.CreatedCallback() {
            @Override
            public void onCreated(LuaView luaView) {
                luaView.load("button.lua");
                llContent.addView(luaView);
            }
        });

    }
}


lua文件

local btn= Button();
btn:title("lua的title")

下面简称LuaViewSDK为lua,一般业务上的需求大体可以分为以下几类,

  • 纯lua加载
  • Lua和native交互
  • native和lua交互
  • 拓展view。

我也将按照上面四个进行编写对应代码,因为我没服务器可以搭建,暂时全部加载本地lua进行展示

代码我会上传到github上,到时候大家下载就可以了。

  • 纯lua加载

我将以最常用的图片Image 和按钮Button,写一个简单的demo

//获取屏幕宽高
w, h = System.screenSize();
local unit = w * 1.0 / 360 * 1.0;
//这里需要将本地图片放到deawable下,可以直接引用
 local hongbao ="hongbao_bg";
//用来加载的网络图片
 local opneUrl="https://xossimg.2cq.com/system/img/play/newbies/b22e4ef39c0968e65ca893604d303b15.png"
​
​
//设置还没打开的图片的宽高
local img_noOepn =Image();
img_noOepn:image(hongbao)
img_noOepn:frame(0,100*unit,252*unit,319*unit)
img_noOepn:alignCenterHorizontal();
//设置加载图片的宽高
local redAward =Image();
redAward:image(opneUrl)
redAward:frame(0,100*unit,252*unit,319*unit)
redAward:alignCenterHorizontal();
redAward:hide();
//设置点击的按钮宽高和位置和图片 title
local btnOpen =Button();
btnOpen:alignCenterHorizontal();
btnOpen:frame(0,350*unit,150*unit,34*unit)
btnOpen:image("btn_yellow_bg","btn_yellow_bg")
btnOpen:title("去往直播间")
btnOpen:titleColor("0xff2233")
btnOpen:hide();
​
​
//点击第一张图片 显示奖励红包 添加点击事件
img_noOepn:onClick( function ()
 img_noOepn :hide()  redAward:show();btnOpen:show() end)

这里因为涉及到图片加载的问题,LuaViewSDK中并没有直接提供图片加载的框架,而是提供了对外的接口

//这里是一个静态方法,设置完以后全局可用
LuaView.registerImageProvider(ImageProvider)
public class GlideImageProvider implements ImageProvider {
    private static final String TAG = "GlideImageProvider";
//加载的时候
    @Override
    public void load(Context context, WeakReference<BaseImageView> imageView, String url, WeakReference<DrawableLoadCallback> callback) {
        ImageView imageView1 = imageView.get();
        Glide.with(context).load(url).into(imageView1);

    }
//重新加载
    @Override
    public void preload(Context context, String url, DrawableLoadCallback callback) {

    }
//不可见的时候
    @Override
    public void pauseRequests(ViewGroup view, Context context) {

    }
//可见的时候
    @Override
    public void resumeRequests(ViewGroup view, Context context) {

    }
}

直接设置LuaView.registerImageProvider(GlideImageProvider)就可以了。我这里面使用的Glide,如何引用Gilde这里我就不做赘述了。对了如果你的手机是高版本手机,比如9和9以上,可能加载非https的图片出不来,是因为android在高版本做了安全限制,具体解决方案度娘就可以了。

多提一嘴,写点击事件的模板是

view:onClick( function ()
   todoxxx() end)
  • Lua和native交互

lua和native交互需要注册一个方法

提供一个类 当做lua和native交互的桥梁,在下面类里面我提供了一个startAcitvity的方法。

/**
 * 被lua打开的页面
 * 测试lua和本地交互
 */
public class LuaOpenNativeBridge {
    private Activity mActivity;

    public LuaOpenNativeBridge(Activity activity) {
        this.mActivity = activity;
    }

    /**
     * 被lua调用的方法
     */
    public void startAcitvity() {
        Intent intent = new Intent();
        intent.setClass(mActivity, LuaOpenNativeActivity.class);
        mActivity.startActivity(intent);
    }

}
luaView.load("newbies.lua");
//注册桥 前面的名字使用来在lua脚本中使用,后面是你的桥类
luaView.register("luaopnenative", new LuaOpenNativeBridge(LuaViewActivity.this));
//注册图片加载(全局一次就可以建议放在初始化)
LuaView.registerImageProvider(GlideImageProvider.class);
//将luaview 添加到布局
llAll.addView(luaView);

还是拿上面的lua做案例,直接在最后按钮上添加点击事件。看最后的代码就可以了

w, h = System.screenSize();
local unit = w * 1.0 / 360 * 1.0;
 local hongbao ="hongbao_bg";
 local opneUrl="https://xossimg.2cq.com/system/img/play/newbies/b22e4ef39c0968e65ca893604d303b15.png"

local img_noOepn =Image();
img_noOepn:image(hongbao)
img_noOepn:frame(0,100*unit,252*unit,319*unit)
img_noOepn:alignCenterHorizontal();

local redAward =Image();
redAward:image(opneUrl)
redAward:frame(0,100*unit,252*unit,319*unit)
redAward:alignCenterHorizontal();
redAward:hide();

local btnOpen =Button();
btnOpen:alignCenterHorizontal();
btnOpen:frame(0,350*unit,150*unit,34*unit)
btnOpen:image("btn_yellow_bg","btn_yellow_bg")
btnOpen:title("去往直播间")
btnOpen:titleColor("0xff2233")
btnOpen:hide();

img_noOepn:onClick( function ()
   img_noOepn :hide()  redAward:show();btnOpen:show() end)
//添加点击事件 
btnOpen:onClick( function ()
   redAward :hide() btnOpen:hide()  Toast("拉取接口,打开直播间")
    //这里的名字和 注册的名字一样,直接掉对应注册类里的方法 
    luaopnenative:startAcitvity()  end)
  • native和lua交互

有时候 我们也希望和lua进行对应的互动 ,这里涉及到一个类LVCustomPanel

这是我写的一个代码,initPanel方法中,写需要做的事情,我这里添加了一个文本输入框,当我输入框,输入东西的时候,我希望lua可以给我吐司出来,回调lua 要用到callLuaCallback 方法。callLuaCallback方法是个可变函数,可以将需要的参数回传给lua

public class NativeOpenLua extends LVCustomPanel {

    private EditText edInput;
    private static final String TAG = "NativeOpenLua";

    public NativeOpenLua(Globals globals, LuaValue metaTable, Varargs varargs) {
        super(globals, metaTable, varargs);
    }

    @Override
    public void initPanel() {
        LayoutInflater localinflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = localinflater.inflate(R.layout.view_nativeopennative, null, false);
        edInput = view.findViewById(R.id.edinput);
        view.findViewById(R.id.btn_send).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                String showContent = edInput.getText().toString();
                if (!TextUtils.isEmpty(showContent)) {
                    callLuaCallback(showContent);
                } else {
                    ToastUtil.showToast(getContext(), "大佬,输入点啥子嘞");
                }

            }
        });
        LayoutParams relativeLayoutParamsMM = LuaViewUtil.createRelativeLayoutParamsMM();
        addView(view,relativeLayoutParamsMM);

    }
}

lua那边就很简单,收到消息就吐司出来

//这里要对应注册的panel名称
panel = NativeOpenLua()
panel:frame(0, 0, w, h)
//回调 对应的参数
panel:callback(function(message)
local showContent =
   Toast("lua显示 您输入的消息为 "..message)
end)

print("rootView", panel.nativeView().getAlpha())

中间需要一个桥来沟通

    luaView.registerPanel(NativeOpenLua.class);
    luaView.load("nativeopenlua.lua");
    llAll.addView(luaView);}

4 拓展view

可能SDK 中包含的View 不够在支撑自己的业务,那么就需要自己添加view到lua中

其实扩展比较简单 ,还是集成LVCustomPanel,在initPanel中将自己写的好view 添加到lua中就可以了

**
 * 显示扩展
 */
public class ShowCustomePanel extends LVCustomPanel {
    public ShowCustomePanel(Globals globals, LuaValue metaTable, Varargs varargs) {
        super(globals, metaTable, varargs);
    }

    @Override
    public void initPanel() {
        LayoutInflater localinflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = localinflater.inflate(R.layout.view_customepanel, null, false);
        view.findViewById(R.id.img_show).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                callLuaCallback("点击去往直播间");
            }
        });
        LayoutParams relativeLayoutParamsMM = LuaViewUtil.createRelativeLayoutParamsMM();
      //添加view
        addView(view, relativeLayoutParamsMM);
    }
}

注册,registerPanel 这里是多构造函数,可以取名字,也可以不取别名,我直接将ShowCustomePanel注册进去。区别在lua脚本里。

luaView.registerPanel(ShowCustomePanel.class);
luaView.load(luaUrl);
panel = ShowCustomePanel()
panel:frame(0, 0, w, h)
panel:callback(function(message)
Toast("即将打开直播间")
luaopnenative:startAcitvity()

end)

是不是发现拓展居然和native和lua交互 基本是一样的?其实想想也是,我都能和lua交互了,我怎么不能把一个view 塞给lua呢。只不过这里的pannel 直接指向了你扩展的view,在这里你的view可以受用lua提供的各种方法,比如size,frame等等方法。

到这里基本就讲解完了LuaViewSDK的入门。如果有其他需求可以去看看api如何使用。有时间我会挨个实验下SDK的Api,财了坑我再同步。

相关文章

网友评论

      本文标题:LuaViewSDK 简单入坑

      本文链接:https://www.haomeiwen.com/subject/fqldhhtx.html