course={
  title={
    笔记={
      --1
      "打印" ;
      --2
      "控件被单击" ;
      --3
      "控件被长按" ;
      --4
      "控件可视，不可视或隐藏" ;
      --5
      "提示框" ;
      --6
      "读写文件" ;
      --7
      "加载框示例" ;
      --8
      "标题栏菜单按钮" ;
      --9
      "关闭对话框" ;
      --10
      "判断是否有网络" ;
      --11
      "沉浸状态栏" ;
      --12
      "复制文本到剪贴板" ;
      --13
      "安卓跳转动画" ;
      --14
      "TextView文本可选择复制" ;
      --15
      "取随机数" ;
      --16
      "延迟" ;
      --17
      "定时器" ;
      --18
      "获取本地时间" ;
      --19
      "字符串操作" ;
      --20
      "设置控件大小" ;
      --21
      "载入窗口传参" ;
      --22
      "EditText只能输数字" ;
      --23
      "窗口全屏" ;
      --24
      "关闭当前窗口" ;
      --25
      "按两次返回键退出" ;
      --26
      "取字符串中间" ;
      --27
      "判断文件是否存在" ;
      --28
      "判断文件夹是否存在" ;
      --29
      "窗口回调事件" ;
      --30
      "隐藏标题栏" ;
      --31
      "自定义布局对话框" ;
      --32
      "列表下滑到最底事件" ;
      --33
      "标题栏返回按钮" ;
      --34
      "列表长按事件" ;
      --35
      "列表点击事件" ;
      --36
      "关于V4的圆形下拉刷新" ;
      --37
      "活动中的回调" ;
      --38
      "对话框Dialog" ;
      --39
      "删除ListView中某项" ;
      --40
      "打开某APP" ;
      --41
      "设置横屏竖屏" ;
      --42
      "设置控件图片" ;
      --43
      "禁用编辑框" ;
      --44
      "隐藏滑条" ;
      --45
      "图片着色" ;
      --46
      "获取IMEI号" ;
      --47
      "分享文字" ;
      --48
      "发送短信" ;
      --49
      "拔号" ;
      --50
      "安装APK" ;
      --51
      "振动" ;
      --52
      "获取剪贴板内容" ;
      --53
      "压缩成ZIP" ;
      --54
      "ZIP解压" ;
      --55
      "删除文件夹" ;
      --56
      "重命名文件夹" ;
      --57
      "创建文件夹" ;
      --58
      "删除文件" ;
      --59
      "设置标题栏标题" ;
      --60
      "获取Lua文件的执行路径" ;
      --61
      "获取本应用包名" ;
      --62
      "布局设置点击效果" ;
      --63
      "判断某APP是否安装" ;
      --64
      "调用系统下载" ;
      --65
      "动画结束回调" ;
      --66
      "关于侧滑" ;
      --67
      "关于输入法影响布局的问题" ;
      --68
      "TextView设置字体样式" ;
      --69
      "强制结束自身并清除自身数据" ;
      --70
      "递归搜索文件实例" ;
      --71
      "获取ListView垂直坐标" ;
      --72
      "申请root权限" ;
      --73
      "传感器" ;
      --74
      "获取控件宽高" ;
      --75
      "播放音频" ;
      --76
      "控件旋转" ;
      --77
      "EditText文本被改变事件";
    },
    Lua教程={
      --1
      "初识AndroLua" ;
      --2
      "Lua简介" ;
      --3
      "第一个 Lua 程序" ;
      --4
      "注释" ;
      --5
      "标示符" ;
      --6
      "关键词" ;
      --7
      "全局变量" ;
      --8
      "Lua 数据类型" ;
      --9
      "nil（空）" ;
      --10
      "boolean（布尔）" ;
      --11
      "number（数字）" ;
      --12
      "string（字符串）" ;
      --13
      "table（表）" ;
      --14
      "function（函数）" ;
      --15
      "thread（线程）" ;
      --16
      "userdata（自定义类型）" ;
      --17
      "Lua 变量" ;
      --18
      "赋值语句" ;
      --19
      "索引" ;
      --20
      "Lua 循环" ;
      --21
      "循环控制语句" ;
      --22
      "无限循环" ;
      --23
      "Lua 流程控制" ;
      --24
      "Lua 函数" ;
      --25
      "Lua 运算符" ;
      --26
      "Lua 字符串" ;
      --27
      "Lua 数组" ;
      --28
      "一维数组" ;
      --29
      "Lua 迭代器" ;
      --30
      "泛型 for 迭代器" ;
      --31
      "无状态的迭代器" ;
      --32
      "多状态的迭代器" ;
      --33
      "Lua 文件 I/O" ;
      --34
      "I/O 简单模式" ;
      --35
      "I/O 完全模式" ;
      --36
      "I/O 的其他方法" ;
      --37
      "Lua 错误处理" ;
      --38
      "语法错误" ;
      --39
      "运行错误" ;
      --40
      "错误处理" ;
      --41
      "error函数" ;
      --42
      "pcall 和 xpcall、debug" ;
      --43
      "Lua 调试(Debug)" ;
      --44
      "调试函数的另一个实例" ;
      --45
      "调试类型" ;
      --46
      "Lua 垃圾回收" ;
      --47
      "垃圾回收器函数" ;
      --48
      "Lua 面向对象" ;
      --49
      "面向对象特征" ;
      --50
      "Lua 中面向对象" ;
      --51
      "Lua 继承" ;
      --52
      "函数重写" ;
    },
    用户界面={
      --1
      "标题栏(ActionBar)" ;
      --2
      "五大布局" ;
      --3
      "Widget(普通控件)" ;
      --4
      "Check View(检查控件)" ;
      --5
      "SeekBar(拖动条)" ;
      --6
      "ProgressBar(进度条)" ;
      --7
      "Adapter View(适配器控件)" ;
      --8
      "LuaWebView(浏览器控件)" ;
      --9
      "AutoCompleteTextView(自动补全文本框)" ;
      --10
      "TimePicker(时间选择器)" ;
      --11
      "DatePicker(日期选择器)" ;
      --12
      "NemberPicker(数值选择器)" ;
      --13
      "AlertDialog(对话框)" ;
      --14
      "ProgressDialog(进度对话框)" ;
      --15
      "InputMethodManager(输入法管理器)" ;
      --16
      "PopMenu(弹出式菜单)" ;
      --17
      "PopWindow(弹出式窗口)" ;
      --18
      "Toast(提示)" ;
      --19
      "控件常用属性" ;
      --20
      "Animation(动画)" ;
      --21
      "LayoutAnimationController(布局动画控制器)" ;
      --22
      "ObjectAnimator(属性动画)" ;
      --23
      "overridePendingTransition(设置窗口动画)" ;
      --24
      "配色参考" ;
    },
    实用代码={
      --1
      "获取设备标识码" ;
      --2
      "获取IMEI" ;
      --3
      "控件背景渐变动画" ;
      --4
      "精准获取屏幕尺寸" ;
      --5
      "发送邮件" ;
      --6
      "自定义默认弹窗标题,消息,按钮的颜色" ;
      --7
      "获取手机存储空间" ;
      --8
      "获取视频第一帧" ;
      --9
      "选择文件模块" ;
      --10
      "选择路径模块" ;
      --11
      "获取视图中的所有文本" ;
      --12
      "控件圆角" ;
      --13
      "匹配汉字" ;
      --14
      "播放音乐与视频" ;
      --15
      "获取系统SDK，Android版本及设备型号" ;
      --16
      "控件颜色修改" ;
      --17
      "修改对话框按钮颜色" ;
      --18
      "查询本地所有视频" ;
      --19
      "查询本地所有图片" ;
      --20
      "递归查找文件" ;
      --21
      "获取手机内置存储路径" ;
      --22
      "获取已安装程序的包名、版本号、最后更新时间、图标、应用名称" ;
      --23
      "获取指定安装包的包名,图标,应用名" ;
      --24
      "获取某程序是否安装" ;
      --25
      "设置TextView字体风格" ;
      --26
      "缩放图片" ;
      --27
      "获取运营商名称" ;
      --28
      "Drawable着色" ;
      --29
      "保存图片到本地" ;
      --30
      "调用应用商店搜索应用" ;
      --31
      "分享" ;
      --32
      "调用其它程序打开文件" ;
      --33
      "图片圆角" ;
      --34
      "一键加群与QQ聊天" ;
      --35
      "发送短信" ;
      --36
      "判断数组中是否存在某个值" ;
      --37
      "字符串操作" ;
      --38
      "剪切板操作" ;
      --39
      "各种事件" ;
      --40
      "Shell执行" ;
    },
    文件操作={
      --1
      "创建新文件" ;
      --2
      "创建新文件夹" ;
      --3
      "重命名与移动文件" ;
      --4
      "追加更新文件" ;
      --5
      "更新文件" ;
      --6
      "写入文件" ;
      --7
      "写入文件(自动创建父文件夹)" ;
      --8
      "读取文件" ;
      --9
      "按行读取文件" ;
      --10
      "删除文件或文件夹" ;
      --11
      "复制文件" ;
      --12
      "递归删除文件夹或文件" ;
      --13
      "替换文件内字符串" ;
      --14
      "获取文件列表" ;
      --15
      "获取文件名称" ;
      --16
      "获取文件大小" ;
      --17
      "获取文件或文件夹最后修改时间" ;
      --18
      "获取文件字节" ;
      --19
      "获取文件父文件夹路径" ;
      --20
      "获取文件Mime类型" ;
      --21
      "判断路径是不是文件夹" ;
      --22
      "判断路径是不是文件" ;
      --23
      "判断文件或文件夹存不存在" ;
      --24
      "判断是不是系统隐藏文件" ;
    },
    基础代码={
      --1
      "打印" ;
      --2
      "注释" ;
      --3
      "字符串" ;
      --4
      "赋值" ;
      --5
      "类型简介" ;
      --6
      "Table(数组)" ;
      --7
      "比较操作符" ;
      --8
      "For循环" ;
      --9
      "While循环" ;
      --10
      "if(判断语句)" ;
      --11
      "function(函数)" ;
      --12
      "基础代码" ;
    },
    Intent类={
      --1
      "Intent类介绍" ;
      --2
      "调用浏览器搜索关键字" ;
      --3
      "调用浏览器打开网页" ;
      --4
      "打开其它程序" ;
      --5
      "安装其它程序" ;
      --6
      "卸载其它程序" ;
      --7
      "播放Mp4" ;
      --8
      "播放Mp3" ;
      --9
      "搜索应用" ;
      --10
      "调用系统设置" ;
      --11
      "调用系统打开文件" ;
      --12
      "调用图库选择图片" ;
      --13
      "调用文件管理器选择文件" ;
      --14
      "分享文件" ;
      --15
      "发送短信" ;
      --16
      "发送彩信" ;
      --17
      "拨打电话" ;
    },
    AndroLua帮助={
      --1
      '关于AndroLua',
      --2
      '软件基本操作',
      --3
      '快速入门',
      --4
      '与标准Lua5.3的不同',
      --5
      '参考链接',
      --6
      '导入模块',
      --7
      '导入包或类',
      --8
      '创建布局与组件',
      --9
      '使用方法',
      --10
      '使用事件',
      --11
      '回调方法',
      --12
      '按键与触控',
      --13
      '使用数组',
      --14
      '使用线程',
      --15
      '使用布局表',
      --16
      '2D绘图',
      --17
      'Lua类型与Java类型',
      --18
      'canvas模块',
      --19
      'OpenGL模块',
      --20
      'http 同步网络模块',
      --21
      'import模块',
      --22
      'Http 异步网络模块',
      --23
      'bmob网络数据库',
      --24
      'LuaUtil 辅助库',
      --25
      'LuaAdapter 适配器',
      --26
      '关于AndroLua打包',
      --27
      '部分函数参考',
      --28
      'activity部分API参考',
      --29
      '布局表字符串常量',
    },
    网络操作={
      --1
      "断开连接并关闭WiFi",
      --2
      "开启/关闭WiFi",
      --3
      "获取WiFi打开状态",
      --4
      "获取WiFi信息",
      --5
      "获取WiFi状态",
      --6
      "获取WiFi加密类型",
      --7
      "获取DNS",
      --8
      "获取WiFi信号强度",
      --9
      "IP地址",
      --10
      "自带Http模块",
      --11
      "TrafficStats类",
      --12
      "WiFi是否连接",
      --13
      "获取SSID是否被隐藏",
      --14
      "获取Mac地址",
      --15
      "数据网络是否连接",
      --16
      "获取网络名称",
    },

  },

  content={
    笔记={
      --1
      "print(打印内容)" ;
      --2
      "function 控件ID.onClick()\
--事件\
end\
\
控件ID.onClick=function()\
--事件\
end" ;
      --3
      "控件ID.onLongClick=function()\
--事件\
end\
\
function 控件ID.onLongClick()\
--事件\
end" ;
      --4
      "--控件可视\
控件ID.setVisibility(View.VISIBLE)\
--控件不可视\
控件ID.setVisibility(View.INVISIBLE)\
--控件隐藏\
控件ID.setVisibility(View.GONE)" ;
      --5
      "import \"android.content.DialogInterface\"\
local dl=AlertDialog.Builder(activity)\
.setTitle(\"提示框标题\")\
.setMessage(\"提示框内容\")\
.setPositiveButton(\"按钮标题\",DialogInterface\
.OnClickListener{\
onClick=function(v)\
--事件\
end\
})\
.setNegativeButton(\"按钮标题\",nil)\
.create()\
dl.show()" ;
      --6
      "--读文件\
local file=io.input(\"地址\")\
local str=io.read(\"*a\")\
io.close()\
print(str)\
--写文件\
local file=io.output(\"地址\")\
io.write(写入内容)\
io.flush()\
io.close()" ;
      --7
      "local dl=ProgressDialog.show(activity,nil,'登录中')\
dl.show()\
local a=0\
local tt=Ticker()\
tt.start()\
tt.onTick=function() \
a=a+1\
if a==3 then\
dl.dismiss()\
tt.stop() \
end\
end" ;
      --8
      "tittle={\"分享\",\"帮助\",\"皮肤\",\"退出\"}\
function onCreateOptionsMenu(menu) \
for k,v in ipairs(tittle) do \
if tittle[v] then \
local m=menu.addSubMenu(v) \
for k,v in ipairs(tittle[v]) do \
m.add(v) \
end \
else \
local m=menu.add(v) \
m.setShowAsActionFlags(1) \
end \
end \
end \
function onMenuItemSelected(id,tittle) \
if y[tittle.getTitle()] then \
y[tittle.getTitle()]() \
end \
end \
\
y={}\
y[\"帮助\"]=function() \
--事件\
end\
\
--菜单\
function onCreateOptionsMenu(menu)\
menu.add(\"打开\").onMenuItemClick=function(a)\
\
end\
menu.add(\"新建\").onMenuItemClick=function(a)\
\
end\
end" ;
      --9
      "--将dl.show赋值\
dialog=dl.show()\
--在某按钮点击后关闭这个对话框\
function zc.onClick()\
dialog.dismiss()\
end" ;
      --10
      "local wl=activity.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE).getActiveNetworkInfo(); \
if wl== nil then\
print(\"无法连接到服务器\")\
end" ;
      --11
      "--这个需要系统SDK21以上才能用\
if Build.VERSION.SDK_INT >= 21 then\
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS).setStatusBarColor(0xff4285f4);\
end\
--这个需要系统SDK19以上才能用\
if Build.VERSION.SDK_INT >= 19 then\
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);\
end" ;
      --12
      "--先导入包\
import \"android.content.*\" \
activity.getSystemService(Context.CLIPBOARD_SERVICE).setText(文本)" ;
      --13
      "android.R.anim.accelerate_decelerate_interpolator\
android.R.anim.accelerate_interpolator\
android.R.anim.anticipate_interpolator\
android.R.anim.anticipate_overshoot_interpolator\
android.R.anim.bounce_interpolator\
android.R.anim.cycle_interpolator\
android.R.anim.decelerate_interpolatoandroid.R.anim.r\
android.R.anim.fade_in\
android.R.anim.fade_out\
android.R.anim.linear_interpolator\
android.R.anim.overshoot_interpolator\
android.R.anim.slide_in_left\
android.R.anim.slide_out_right" ;
      --14
      "--代码中设置\
t.TextIsSelectable=true\
--布局表中设置\
textIsSelectable=true" ;
      --15
      "math.random(最小值,最大值)" ;
      --16
      "--这个会卡进程，配合线程使用\
Thread.sleep(延迟时间)\
--这个不会卡进程\
--500指延迟500毫秒\
task(500‚function()\
--延迟之后执行的事件\
end)" ;
      --17
      "--timer定时器\
t=timer(function() \
--事件\
end,延迟,间隔,初始化)\
--暂停timer定时器\
t.Enable=false\
--启动timer定时器\
t.Enable=true\
\
--Ticker定时器\
ti=Ticker()\
ti.Period=间隔\
ti.onTick=function() \
--事件\
end\
--启动Ticker定时器\
ti.start()\
--停止Ticker定时器\
ti.stop()" ;
      --18
      "--格式的时间\
os.date(\"%Y-%m-%d %H:%M:%S\")\
--本地时间总和\
os.clock()\
《《EditText文本被改变事件\
控件ID.addTextChangedListener{\
onTextChanged=function(s)\
--事件\
end\
}" ;
      --19
      "--字符串转大写\
string.upper(字符串)\
--字符串转小写\
string.lower(字符串)\
--字符串替换\
string.gsub(字符串,被替换的字符,替换的字符,替换次数)" ;
      --20
      "--设置宽度\
linearParams = 控件ID.getLayoutParams()\
linearParams.width =宽度\
控件ID.setLayoutParams(linearParams)\
--同理设置高度\
linearParams = 控件ID.getLayoutParams()\
linearParams.height =高度\
控件ID.setLayoutParams(linearParams)" ;
      --21
      "activity.newActivity(\"窗口名\",{参数})\
\
--渐变动画效果的，中间是安卓跳转动画代码\
activity.newActivity(\"窗口名\",android.R.anim.fade_in,android.R.anim.fade_out,{参数})" ;
      --22
      "import \"android.text.InputType\"\
import \"android.text.method.DigitsKeyListener\"\
控件ID.setInputType(InputType.TYPE_CLASS_NUMBER)\
控件ID.setKeyListener(DigitsKeyListener.getInstance(\"0123456789\"))" ;
      --23
      "activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)" ;
      --24
      "activity.finish()" ;
      --25
      "参数=0\
function onKeyDown(code,event) \
if string.find(tostring(event),\"KEYCODE_BACK\") ~= nil then \
if 参数+2 > tonumber(os.time()) then \
activity.finish()\
else\
 Toast.makeText(activity,\"再按一次返回键退出\" , Toast.LENGTH_SHORT )\
.show()\
参数=tonumber(os.time()) \
end\
return true \
end\
end" ;
      --26
      "string.match(\"左测试测试右\",\"左(.-)右\")" ;
      --27
      "--先导入io包\
import \"java.io.*\"\
file,err=io.open(\"路径\")\
print(err)\
if err==nil then\
print(\"存在\")\
else\
print(\"不存在\")\
end" ;
      --28
      "--先导入io包\
import \"java.io.*\"\
if File(文件夹路径).isDirectory()then\
print(\"存在\")\
else\
print(\"不存在\")\
end" ;
      --29
      "function onActivityResult()\
--事件\
end" ;
      --30
      "activity.ActionBar.hide()" ;
      --31
      "local dl=AlertDialog.Builder(activity)\
.setTitle(\"自定义布局对话框\")\
.setView(loadlayout(layout))\
dl.show()" ;
      --32
      "list.setOnScrollListener{\
onScrollStateChanged=function(l,s)\
if list.getLastVisiblePosition()==list.getCount()-1 then\
--事件\
end\
end}" ;
      --33
      "activity.getActionBar().setDisplayHomeAsUpEnabled(true) " ;
      --34
      "ID.setOnItemLongClickListener(AdapterView.OnItemLongClickListener{\
onItemLongClick=function(parent, v, pos,id)\
--事件\
end\
})" ;
      --35
      "ID.setOnItemClickListener(AdapterView.OnItemClickListener{\
onItemClick=function(parent, v, pos,id)\
--事件\
end\
})" ;
      --36
      "--设置下拉刷新监听事件\
swipeRefreshLayout.setOnRefreshListener(this);\
--设置进度条的颜色\
swipeRefreshLayout.setColorSchemeColors(Color.RED, Color.BLUE, Color.GREEN);\
--设置圆形进度条大小\
swipeRefreshLayout.setSize(SwipeRefreshLayout.LARGE);\
--设置进度条背景颜色\
swipeRefreshLayout.setProgressBackgroundColorSchemeColor(Color.DKGRAY);\
--设置下拉多少距离之后开始刷新数据\
swipeRefreshLayout.setDistanceToTriggerSync(50);" ;
      --37
      "function main(...)\
--...是newActivity传递过来的参数。\
print(\"入口函数\",...)\
end\
\
function onCreate()\
print(\"窗口创建\")\
end\
\
function onStart()\
print(\"活动开始\")\
end\
\
function onResume()\
print(\"返回程序\")\
end\
\
function onPause()\
print(\"活动暂停\")\
end\
\
function onStop()\
print(\"活动停止\")\
end\
\
function onDestroy()\
print(\"程序已退出\")\
end\
\
function onResult(name,...)\
--name：返回的活动名称\
--...：返回的参数\
print(\"返回活动\",name,...)\
end\
\
function onCreateOptionsMenu(menu)\
--menu：选项菜单。\
menu.add(\"菜单\")\
end\
\
function onOptionsItemSelected(item)\
--item：选中的菜单项\
print(item.Title)\
end\
\
function onConfigurationChanged(config)\
--config：配置信息\
print(\"屏幕方向关闭\")\
end\
\
function onKeyDown(keycode,event)\
--keycode：键值\
--event：事件\
print(\"按键按下\",keycode)\
end\
\
function onKeyUp(keycode,event)\
--keycode：键值\
--event：事件\
print(\"按键抬起\",keycode)\
end\
\
function onKeyLongPress(keycode,event)\
--keycode：键值\
--event：事件\
print(\"按键长按\",keycode)\
end\
\
function onTouchEvent(event)\
--event：事件\
print(\"触摸事件\",event)\
end" ;
      --38
      "--简单对话框\
AlertDialog.Builder(this).setTitle(\"标题\")\
.setMessage(\"简单消息框\")\
.setPositiveButton(\"确定\",nil)\
.show();\
\
--带有三个按钮的对话框\
AlertDialog.Builder(this) \
.setTitle(\"确认\")\
.setMessage(\"确定吗？\")\
.setPositiveButton(\"是\",nil)\
.setNegativeButton(\"否\",nil)\
.setNeutralButton(\"不知道\",nil)\
.show();\
\
--带输入框的\
AlertDialog.Builder(this)\
.setTitle(\"请输入\")\
.setIcon(android.R.drawable.ic_dialog_info)\
.setView(EditText(this))\
.setPositiveButton(\"确定\", nil)\
.setNegativeButton(\"取消\", nil)\
.show();\
\
--单选的\
AlertDialog.Builder(this)\
.setTitle(\"请选择\")\
.setIcon(android.R.drawable.ic_dialog_info)\
.setSingleChoiceItems({\"选项1\",\"选项2\",\"选项3\",\"选项4\"}, 0, \
DialogInterface.OnClickListener() {\
 onClick(dialog,which) {\
dialog.dismiss();\
 }\
}\
)\
.setNegativeButton(\"取消\", null)\
.show();\
\
--多选的\
AlertDialog.Builder(this)\
.setTitle(\"多选框\")\
.setMultiChoiceItems({\"选项1\",\"选项2\",\"选项3\",\"选项4\"}, null, null)\
.setPositiveButton(\"确定\", null)\
.setNegativeButton(\"取消\", null)\
.show();\
\
--列表的\
AlertDialog.Builder(this)\
.setTitle(\"列表框\")\
.setItems({\"列表项1\",\"列表项2\",\"列表项3\"},nil)\
.setNegativeButton(\"确定\",nil)\
.show();\
\
--图片的\
img = ImageView(this);\
img.setImageResource(R.drawable.icon);\
AlertDialog.Builder(this)\
.setTitle(\"图片框\")\
.setView(img)\
.setPositiveButton(\"确定\",nil)\
.show();" ;
      --39
      "adp.remove(pos)" ;
      --40
      "--导入包\
import \"android.content.*\"\
\
intent = Intent();\
componentName = ComponentName(\"com.androlua\",\"com.androlua.Welcome\"); \
intent.setComponent(componentName); \
activity.startActivity(intent);" ;
      --41
      "--横屏\
activity.setRequestedOrientation(0); \
--竖屏\
activity.setRequestedOrientation(1); " ;
      --42
      "--设置的图片也可以输入路径\
ID.setImageBitmap(loadbitmap(\"图片.png\"))" ;
      --43
      "--代码中设置\
editText.setFocusable(false);\
--布局表中设置\
Focusable=false;" ;
      --44
      "--横向\
horizontalScrollBarEnabled=false;\
--竖向\
VerticalScrollBarEnabled=false;" ;
      --45
      "--代码中设置\
ID.setColorFilter(0xffff0000)\
--布局表中设置\
ColorFilter=\"#ffff0000\"；" ;
      --46
      "import \"android.content.*\" \
--导入包 \
\
imei=activity.getSystemService(Context.TELEPHONY_SERVICE).getDeviceId(); \
print(imei) \
\
--别忘了添加权限\"READ_PHONE_STATE\" " ;
      --47
      "import \"android.content.*\" \
\
text=\"分享的内容\" \
intent=Intent(Intent.ACTION_SEND); \
intent.setType(\"text/plain\"); \
intent.putExtra(Intent.EXTRA_SUBJECT, \"分享\"); \
intent.putExtra(Intent.EXTRA_TEXT, text); \
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); \
activity.startActivity(Intent.createChooser(intent,\"分享到:\")); " ;
      --48
      "--导入包\
import \"android.content.*\" \
import \"android.net.*\" \
\
uri = Uri.parse(\"smsto:15800001234\"); \
intent = Intent(Intent.ACTION_SENDTO, uri); \
intent.putExtra(\"sms_body\",\"你好\") \
intent.setAction(\"android.intent.action.VIEW\"); \
activity.startActivity(intent); " ;
      --49
      "import \"android.content.*\" \
import \"android.net.*\" \
--导入包 \
uri = Uri.parse(\"tel:15800001234\"); \
intent = Intent(Intent.ACTION_CALL, uri); \
intent.setAction(\"android.intent.action.VIEW\"); \
activity.startActivity(intent); \
--记得添加打电话权限 " ;
      --50
      "import \"android.content.*\" \
import \"android.net.*\" \
\
intent = Intent(Intent.ACTION_VIEW); \
intent.setDataAndType(Uri.parse(\"file:///sdcard/jc.apk\"), \"application/vnd.android.package-archive\"); \
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); \
activity.startActivity(intent); " ;
      --51
      "import \"android.content.Context\" \
--导入包 \
vibrator = activity.getSystemService(Context.VIBRATOR_SERVICE) \
vibrator.vibrate( long{100,800} ,-1) \
--{等待时间,振动时间,等待时间,振动时间,•••,•••,•••,•••••} \
--{0,1000,500,1000,500,1000} \
--别忘了申明权限" ;
      --52
      "import\"android.content.*\"\
--导入包\
a=activity.getSystemService(Context.CLIPBOARD_SERVICE).getText()" ;
      --53
      "ZipUtil.zip(\"文件或文件夹路径\",\"压缩到的路径\")" ;
      --54
      "ZipUtil.unzip(\"ZIP路径\",\"解压到的路径\")\
\
--另一种Java方法\
import \"java.io.FileOutputStream\"\
import \"java.util.zip.ZipFile\"\
import \"java.io.File\"\
\
zipfile = \"/sdcard/压缩包.zip\"--压缩文件路径和文件名\
sdpath = \"/sdcard/文件.lua\"--解压后路径和文件名\
zipfilepath = \"内容.lua\"--需要解压的文件名\
\
function unzip(zippath , outfilepath , filename)\
\
local time=os.clock()\
  task(function(zippath,outfilepath,filename)\
require \"import\"\
import \"java.util.zip.*\"\
import \"java.io.*\"\
local file = File(zippath)\
local outFile = File(outfilepath)\
local zipFile = ZipFile(file)\
local entry = zipFile.getEntry(filename)\
local input = zipFile.getInputStream(entry)\
local output = FileOutputStream(outFile)\
local byte=byte[entry.getSize()]\
local temp=input.read(byte)\
while temp ~= -1 do\
output.write(byte)\
temp=input.read(byte)\
end\
input.close()\
output.close()\
end,zippath,outfilepath,filename,\
function()\
print(\"解压完成，耗时 \"..os.clock()-time..\" s\")\
end)\
\
end\
\
unzip(zipfile,sdpath,zipfilepath)" ;
      --55
      "--shell命令的方法\
os.execute(\"rm-r 路径\")" ;
      --56
      "--shell命令的方法\
os.execute(\"mv 路径新路径\")" ;
      --57
      "--shell命令的方法\
os.execute(\"mkdir 路径\")" ;
      --58
      "os.remove(\"路径\")" ;
      --59
      "--标题\
activity.setTitle('标题')\
--小标题\
activity.getActionBar().setSubtitle('小标题')" ;
      --60
      "activity.getLuaDir()" ;
      --61
      "activity.getPackageName()" ;
      --62
      "--5.0或以上可以实现点击水波纹效果\
--在布局加入：\
\
style=\"?android:attr/buttonBarButtonStyle\";" ;
      --63
      "if pcall(function() activity.getPackageManager().getPackageInfo(\"包名\",0) end) then\
print(\"安装了\")\
else\
print(\"没安装\")\
end" ;
      --64
      "--导入包\
import \"android.content.Context\"\
import \"android.net.Uri\"\
\
downloadManager=activity.getSystemService(Context.DOWNLOAD_SERVICE);\
url=Uri.parse(\"绝对下载链接\");\
request=DownloadManager.Request(url);\
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE|DownloadManager.Request.NETWORK_WIFI);\
request.setDestinationInExternalPublicDir(\"目录名，可以是Download\",\"下载的文件名\");\
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);\
downloadManager.enqueue(request);" ;
      --65
      "--导入包\
import \"android.view.animation.*\"\
import \"android.view.animation.Animation$AnimationListener\"\
--控件动画\
控件.startAnimation(AlphaAnimation(1,0).setDuration(400).setFillAfter(true).setAnimationListener(AnimationListener{\
onAnimationEnd=function()\
print\"动画结束\")\
end}))" ;
      --66
      "--侧滑布局是 DrawerLayout;\
--关闭侧滑\
ID.closeDrawer(3)\
--打开侧滑\
ID.openDrawer(3)" ;
      --67
      "--使弹出的输入法不影响布局\
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);\
--使弹出的输入法影响布局\
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);" ;
      --68
      "--首先要导入包\
import \"android.graphics.*\"\
--设置中划线\
控件id.getPaint().setFlags(Paint. STRIKE_THRU_TEXT_FLAG)\
--下划线\
控件id.getPaint().setFlags(Paint. UNDERLINE_TEXT_FLAG )\
--加粗\
控件id.getPaint().setFakeBoldText(true)\
--斜体\
控件id.getPaint().setTextSkewX(0.2)\
\
--设置TypeFace\
import \"android.graphics.Typeface\"\
id.getPaint().setTypeface(字体)\
--字体可以为以下\
Typeface.DEFAULT --默认字体\
Typeface.DEFAULT_BOLD --加粗字体\
Typeface.MONOSPACE --monospace字体\
Typeface.SANS_SERIF --sans字体\
Typeface.SERIF --serif字体" ;
      --69
      " os.execute(\"pm clear \"..activity.getPackageName())" ;
      --70
      "require \"import\"\
\
function find(catalog,name)\
local n=0\
local t=os.clock()\
local ret={}\
require \"import\"\
import \"java.io.File\" \
import \"java.lang.String\"\
function FindFile(catalog,name)\
local name=tostring(name)\
local ls=catalog.listFiles() or File{}\
for 次数=0,#ls-1 do\
--local 目录=tostring(ls[次数])\
local f=ls[次数]\
if f.isDirectory() then--如果是文件夹则继续匹配\
FindFile(f,name)\
else--如果是文件则\
n=n+1\
if n%1000==0 then\
--print(n,os.clock()-t)\
end\
local nm=f.Name\
if string.find(nm,name) then\
--thread(insert,目录)\
table.insert(ret,nm)\
print(nm)\
end\
end\
luajava.clear(f)\
end\
end\
FindFile(catalog,name)\
print(\"ok\",n,#ret)\
end\
\
import \"java.io.File\"\
\
catalog=File(\"sdcard/\")\
name=\".j?pn?g\"\
--task(find,catalog,name,print)\
thread(find,catalog,name)" ;
      --71
      "function getScrollY()\
c = ls.getChildAt(0);\
local firstVisiblePosition = ls.getFirstVisiblePosition();\
local top = c.getTop();\
return -top + firstVisiblePosition * c.getHeight() ;\
end" ;
      --72
      "--shell命令的方法\
os.execute(\"su\")" ;
      --73
      "传感器 = activity.getSystemService(Context.SENSOR_SERVICE)\
\
local 加速度传感器 = 传感器.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)\
传感器.registerListener(SensorEventListener({ \
onSensorChanged=function(event) \
x轴 = event.values[0]\
y轴 = event.values[1]\
z轴 = event.values[2]\
end,nil}), 加速度传感器, SensorManager.SENSOR_DELAY_NORMAL)\
\
local 光线传感器 = 传感器.getDefaultSensor(Sensor.TYPE_LIGHT)\
传感器.registerListener(SensorEventListener({ \
onSensorChanged=function(event) \
光线 = event.values[0]\
end,nil}), 光线传感器, SensorManager.SENSOR_DELAY_NORMAL)\
\
local 距离传感器 = 传感器.getDefaultSensor(Sensor.TYPE_PROXIMITY)\
传感器.registerListener(SensorEventListener({ \
onSensorChanged=function(event) \
距离 = event.values[0]\
end,nil}), 距离传感器, SensorManager.SENSOR_DELAY_NORMAL)\
\
local 磁场传感器 = 传感器.getDefaultSensor(Sensor.TYPE_ORIENTATION)\
传感器.registerListener(SensorEventListener({ \
onSensorChanged=function(event) \
磁场 = event.values[0]\
end,nil}), 磁场传感器, SensorManager.SENSOR_DELAY_NORMAL)\
\
local 温度传感器 = 传感器.getDefaultSensor(Sensor.TYPE_TEMPERATURE)\
传感器.registerListener(SensorEventListener({ \
onSensorChanged=function(event) \
温度 = event.values[0]\
end,nil}), 温度传感器, SensorManager.SENSOR_DELAY_NORMAL)\
\
local 陀螺仪传感器 = 传感器.getDefaultSensor(Sensor.TYPE_GYROSCOPE)\
传感器.registerListener(SensorEventListener({ \
onSensorChanged=function(event) \
陀螺仪 = event.values[0]\
end,nil}), 陀螺仪传感器, SensorManager.SENSOR_DELAY_NORMAL)\
\
local 重力传感器 = 传感器.getDefaultSensor(Sensor.TYPE_GRAVITY)\
传感器.registerListener(SensorEventListener({ \
onSensorChanged=function(event) \
重力 = event.values[0]\
end,nil}), 重力传感器, SensorManager.SENSOR_DELAY_NORMAL)\
\
local 压力传感器 = 传感器.getDefaultSensor(Sensor.TYPE_PRESSURE)\
传感器.registerListener(SensorEventListener({ \
onSensorChanged=function(event) \
压力 = event.values[0]\
end,nil}), 压力传感器, SensorManager.SENSOR_DELAY_NORMAL)" ;
      --74
      "--导入包\
import \"android.content.Context\"\
\
function getwh(view)\
view.measure(View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED),View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED));\
height =view.getMeasuredHeight();\
width =view.getMeasuredWidth();\
return width,height\
end\
\
print(getwh(控件ID))" ;
      --75
      "--导入包\
import \"android.media.MediaPlayer\"\
\
local 音频播放器=MediaPlayer()\
function 播放音频(路径)\
音频播放器.reset()\
.setDataSource(路径)\
.prepare()\
.start()\
.setOnCompletionListener({\
onCompletion=function()\
print(\"播放完毕\")\
end})\
end" ;
      --76
      "--Z轴上的旋转角度\
View.getRotation()\
\
--X轴上的旋转角度\
View.getRotationX()\
\
--Y轴上的旋转角度\
View.getRotationY()\
\
--设置Z轴上的旋转角度\
View.setRotation(r)\
\
--设置X轴上的旋转角度\
View.setRotationX(r)\
\
--设置Y轴上的旋转角度\
View.setRotationY(r)\
\
--设置旋转中心点的X坐标\
View.setPivotX(p)\
\
--设置旋转中心点的Y坐标\
View.setPivotX(p)\
\
--设置摄像机的与旋转目标在Z轴上距离\
View.setCameraDistance(d)" ;
      --77
      "控件ID.addTextChangedListener{\
onTextChanged=function(s)\
--事件\
end\
}》》\
";
    },
    Lua教程={
      --1
      "AndroLua可以在安卓平台上的用 Lua 开发安卓程序，不仅支持调用Java API，而且支持编写安卓界面程序，还可以将自己写的 Lua 程序打包成apk安装文件安装。Lua 语言的简单使没有任何编程经验的用户也能在短时间内开发出安卓程序，因此，在学习AndroLua之前我们需要先学习 Lua 语言。" ;
      --2
      "Lua 是一种轻量小巧的脚本语言，用标准C语言编写并以源代码形式开放， 其设计目的是为了嵌入应用程序中，从而为应用程序提供灵活的扩展和定制功能。\
Lua 是巴西里约热内卢天主教大学（Pontifical Catholic University of Rio de Janeiro）里的一个研究小组，由Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo所组成并于1993年开发。\
那么我们废话不多说来写第一个 Lua 程序吧！" ;
      --3
      "接下来我们使用 Lua 来输出\"Hello World\"\
\
print(\"Hello World\")\
\
运行后，会在屏幕上显示 Hello world" ;
      --4
      "单行注释:\
两个减号是单行注释:\
\
--注释" ;
      --5
      "Lua 表示符用于定义一个变量，函数获取其他用户定义的项。标示符以一个字母 A 到 Z 或 a 到 z 或下划线 _ 开头后加上0个或多个字母，下划线，数字（0到9）。\
最好不要使用下划线加大写字母的标示符，因为Lua的保留字也是这样的。\
Lua 不允许使用特殊字符如 @, $, 和 % 来定义标示符。 Lua 是一个区分大小写的编程语言。因此在 Lua 中 W3c 与 w3c 是两个不同的标示符。以下列出了一些正确的标示符：\
\
mohd         zara      abc     move_name\
\
myname50     _temp     j       a23b9  " ;
      --6
      "以下列出了 Lua 的保留关键字。保留关键字不能作为常量或变量或其他用户自定义标示符：\
\
and      break\9     do      else    elseif   end       false\
for      function  if      in      local    nil\9       not\
or\9      repeat    return\9 then    true     until     while\
\
一般约定，以下划线开头连接一串大写字母的名字（比如 _VERSION）被保留用于 Lua 内部全局变量。" ;
      --7
      "在默认情况下，变量总是认为是全局的。\
全局变量不需要声明，给一个变量赋值后即创建了这个全局变量，访问一个没有初始化的全局变量也不会出错，只不过得到的结果是：nil。\
\
print(b)\
--nil\
b=10\
print(b)\
--10\
\
如果你想删除一个全局变量，只需要将变量赋值为nil。\
\
b = 2\
b = nil\
print(b)\
--nil\
\
这样变量b就好像从没被使用过一样。换句话说, 当且仅当一个变量不等于nil时，这个变量即存在。" ;
      --8
      "Lua是动态类型语言，变量不要类型定义,只需要为变量赋值。 值可以存储在变量中，作为参数传递或结果返回。\
Lua中有8个基本类型分别为：\
\
nil、boolean、number、string、userdata、function、thread和table。\
\
我们可以使用type函数测试给定变量或者值的类型：\
\
print(type(\"Hello world\"))\
--string\
print(type(10.4*3))\
--number\
print(type(print))\
--function\
print(type(type))\
--function\
print(type(true))\
--boolean\
print(type(nil))\
--nil\
print(type(type(X)))\
--string" ;
      --9
      "nil 类型表示一种没有任何有效值，它只有一个值 -- nil，例如打印一个没有赋值的变量，便会输出一个 nil 值：\
\
print(type(a))\
--nil\
\
对于全局变量和 table，nil 还有一个\"删除\"作用，给全局变量或者 table 表里的变量赋一个 nil 值，等同于把它们删掉。" ;
      --10
      "boolean 类型只有两个可选值：true（真） 和 false（假），Lua 把 false 和 nil 看作是\"假\"，其他的都为\"真\"。" ;
      --11
      "Lua 默认只有一种 number 类型 -- double（双精度）类型（默认类型可以修改 luaconf.h 里的定义），以下几种写法都被看作是 number 类型。" ;
      --12
      "字符串由一对双引号或单引号来表示。\
\
string1 = \"this is string1\"\
string2 = 'this is string2'\
\
在对一个数字字符串上进行算术操作时，Lua 会尝试将这个数字字符串转成一个数字，字符串连接使用的是 ..如：\
\
print(\"a\" .. 'b')\
--ab\
print(157 .. 428)\
--157428\
\
使用 # 来计算字符串的长度，放在字符串前面，如下实例：\
\
len = \"www.androlua.com\"\
print(#len)\
--16" ;
      --13
      "在 Lua 里，table 的创建是通过\"构造表达式\"来完成，最简单构造表达式是{}，用来创建一个空表。也可以在表里添加一些数据，直接初始化表:\
\
-- 创建一个空的 table\
local tbl1 = {}\
\
-- 直接初始表\
local tbl2 = {\"apple\", \"pear\", \"orange\", \"grape\"}\
\
Lua 中的表（table）其实是一个\"关联数组\"（associative arrays），数组的索引可以是数字或者是字符串。不同于其他语言的数组把 0 作为数组的初始索引，在 Lua 里表的默认初始索引一般以 1 开始。table 不会固定长度大小，有新数据添加时 table 长度会自动增长，没初始的 table 都是 nil。" ;
      --14
      "在 Lua 中，函数是被看作是\"第一类值（First-Class Value）\"，函数可以存在变量里:\
\
function factorial1(n)\
    if n == 0 then\
        return 1\
    else\
        return n * factorial1(n - 1)\
    end\
end\
print(factorial1(5))\
factorial2 = factorial1\
print(factorial2(5))\
\
function 可以以匿名函数（anonymous function）的方式通过参数传递:\
\
function anonymous(tab, fun)\
    for k, v in pairs(tab) do\
        print(fun(k, v))\
    end\
end\
tab = { key1 = \"val1\", key2 = \"val2\" }\
anonymous(tab, function(key, val)\
    return key .. \" = \" .. val\
end)" ;
      --15
      "在 Lua 里，最主要的线程是协同程序（coroutine）。它跟线程（thread）差不多，拥有自己独立的栈、局部变量和指令指针，可以跟其他协同程序共享全局变量和其他大部分东西。\
线程跟协程的区别：线程可以同时多个运行，而协程任意时刻只能运行一个，并且处于运行状态的协程只有被挂起（suspend）时才会暂停。" ;
      --16
      "userdata 是一种用户自定义数据，用于表示一种由应用程序或 C/C++ 语言库所创建的类型，可以将任意 C/C++ 的任意数据类型的数据（通常是 struct 和 指针）存储到 Lua 变量中调用。" ;
      --17
      "变量在使用前，必须在代码中进行声明，即创建该变量。\
编译程序执行代码之前编译器需要知道如何给语句变量开辟存储区，用于存储变量的值。\
Lua 变量有三种类型：全局变量、局部变量、表中的域。\
Lua 中的变量全是全局变量，那怕是语句块或是函数里，除非用 local 显示声明为局部变量。\
局部变量的作用域为从声明位置开始到所在语句块结束。\
变量的默认值均为 nil。\
\
a = 5               -- 全局变量\
local b = 5         -- 局部变量\
\
function joke()\
    c = 5           -- 全局变量\
    local d = 6     -- 局部变量\
end" ;
      --18
      "赋值是改变一个变量的值和改变表域的最基本的方法。\
\
a = \"hello\" .. \"world\"\
t.n = t.n + 1\
\
Lua可以对多个变量同时赋值，变量列表和值列表的各个元素用逗号分开，赋值语句右边的值会依次赋给左边的变量。\
\
a, b = 10, 2*x       <-->       a=10; b=2*x\
\
遇到赋值语句Lua会先计算右边所有的值然后再执行赋值操作，所以我们可以这样进行交换变量的值：\
\
x, y = y, x                     -- swap 'x' for 'y'\
a[i], a[j] = a[j], a[i]         -- swap 'a[i]' for 'a[j]'\
\
当变量个数和值的个数不一致时，Lua会一直以变量个数为基础采取以下策略：\
a. 变量个数 > 值的个数             按变量个数补足nil\
b. 变量个数 < 值的个数             多余的值会被忽略\
例如：\
\
a, b, c = 0, 1\
print(a,b,c)             --> 0   1   nil\
\
a, b = a+1, b+1, b+2     -- value of b+2 is ignored\
print(a,b)               --> 1   2\
\
a, b, c = 0\
print(a,b,c)             --> 0   nil   nil\
\
上面最后一个例子是一个常见的错误情况，注意：如果要对多个变量赋值必须依次对每个变量赋值。\
\
a, b, c = 0, 0, 0\
print(a,b,c)             --> 0   0   0\
\
多值赋值经常用来交换变量，或将函数调用返回给变量：\
\
a, b = f()\
f()\
\
返回两个值，第一个赋给a，第二个赋给b。\
应该尽可能的使用局部变量，有两个好处：\
1. 避免命名冲突。\
2. 访问局部变量的速度比全局变量更快。" ;
      --19
      "对 table 的索引使用方括号 []。Lua 也提供了 . 操作。\
\
t[i]\
t.i                 -- 当索引为字符串类型时的一种简化写法\
gettable_event(t,i) -- 采用索引访问本质上是一个类似这样的函数调用\
\
例如：\
\
site = {}\
site[\"key\"] = \"www.androlua.cn\"\
print(site[\"key\"])\
--www.androlua.cn\
print(site.key)\
--www.androlua.cn" ;
      --20
      "很多情况下我们需要做一些有规律性的重复操作，因此在程序中就需要重复执行某些语句。\
一组被重复执行的语句称之为循环体，能否继续重复，决定循环的终止条件。\
循环结构是在一定条件下反复执行某段程序的流程结构，被反复执行的程序被称为循环体。\
循环语句是由循环体及循环的终止条件两部分组成的。\
Lua 语言提供了以下几种循环处理方式：\
\
while 循环\
在条件为 true 时，让程序重复地执行某些语句。执行语句前会先检查条件是否为 true。\
\
for 循环\
重复执行指定语句，重复次数可在 for 语句中控制。\
\
Lua repeat...until\
重复执行循环，直到 指定的条件为真时为止\
\
循环嵌套\
可以在循环内嵌套一个或多个循环语句（while、for、do..while）" ;
      --21
      "循环控制语句用于控制程序的流程， 以实现程序的各种结构方式。\
Lua 支持以下循环控制语句：\
\
break 语句\
退出当前循环或语句，并开始脚本执行紧接着的语句。" ;
      --22
      "在循环体中如果条件永远为 true 循环语句就会永远执行下去，以下以 while 循环为例：\
\
while( true )\
do\
   print(\"循环将永远执行下去\")\
end" ;
      --23
      "Lua 编程语言流程控制语句通过程序设定一个或多个条件语句来设定。在条件为 true 时执行指定程序代码，在条件为 false 时执行其他指定代码。\
控制结构的条件表达式结果可以是任何值，Lua认为false和nil为假，true和非nil为真。\
要注意的是Lua中 0 为 true\
\
Lua 提供了以下控制结构语句：\
if 语句\
if 语句由一个布尔表达式作为条件判断，其后紧跟其他语句组成\
\
if...else 语句\
if 语句 可以与 else 语句搭配使用, 在 if 条件表达式为 false 时执行 else 语句代码\
\
if 嵌套语句\
你可以在if 或 else if中使用一个或多个 if 或 else if 语句" ;
      --24
      "在Lua中，函数是对语句和表达式进行抽象的主要方法。既可以用来处理一些特殊的工作，也可以用来计算一些值。\
Lua 提供了许多的内建函数，你可以很方便的在程序中调用它们，如print()函数可以将传入的参数打印在控制台上。\
Lua 函数主要有两种用途：\
1.完成指定的任务，这种情况下函数作为调用语句使用；\
2.计算并返回值，这种情况下函数作为赋值语句的表达式使用。\
以下实例定义了函数 max()，参数为 num1, num2，用于比较两值的大小，并返回最大值：\
\
function max(num1, num2)\
\
   if (num1 > num2) then\
      result = num1;\
   else\
      result = num2;\
   end\
\
   return result;\
end\
-- 调用函数\
print(\"两值比较最大值为 \",max(10,4))\
print(\"两值比较最大值为 \",max(5,6))\
\
Lua 中我们可以将函数作为参数传递给函数，如下实例：\
\
myprint = function(param)\
   print(\"这是打印函数 -   ##\",param,\"##\")\
end\
\
function add(num1,num2,functionPrint)\
   result = num1 + num2\
   -- 调用传递的函数参数\
   functionPrint(result)\
end\
myprint(10)\
-- myprint 函数作为参数传递\
add(2,5,myprint)\
\
Lua函数中，在return后列出要返回的值得列表即可返回多值，如：\
\
\
function maximum (a)\
    local mi = 1             -- 最大值索引\
    local m = a[mi]          -- 最大值\
    for i,val in ipairs(a) do\
       if val > m then\
           mi = i\
           m = val\
       end\
    end\
    return m, mi\
end\
\
print(maximum({8,10,23,12,5}))\
\
Lua函数可以接受可变数目的参数，和C语言类似在函数参数列表中使用三点（...) 表示函数有可变的参数。\
Lua将函数的参数放在一个叫arg的表中，#arg 表示传入参数的个数。\
例如，我们计算几个数的平均值：\
\
function average(...)\
   result = 0\
   local arg={...}\
   for i,v in ipairs(arg) do\
      result = result + v\
   end\
   print(\"总共传入 \" .. #arg .. \" 个数\")\
   return result/#arg\
end\
\
print(\"平均值为\",average(10,5,3,4,5,6))" ;
      --25
      "运算符是一个特殊的符号，用于告诉解释器执行特定的数学或逻辑运算。Lua提供了以下几种运算符类型：\
\
算术运算符,关系运算符,逻辑运算符,其他运算符\
\
算术运算符\
下表列出了 Lua 语言中的常用算术运算符，设定 A 的值为10，B 的值为 20：\
\
+\9加法\9A + B 输出结果 30\
-\9减法\9A - B 输出结果 -10\
*\9乘法\9A * B 输出结果 200\
/\9除法\9B / A 输出结果 2\
%\9取余\9B % A 输出结果 0\
^\9乘幂\9A^2   输出结果 100\
-\9负号\9-A    输出结果v -10\
\
关系运算符\
下表列出了 Lua 语言中的常用关系运算符，设定 A 的值为10，B 的值为 20：\
\
\
==\9等于，检测两个值是否相等，相等返回 true，\
否则返回 false\9(A == B) 为 false。\
~=\9不等于，检测两个值是否相等，相等返回 false，\
否则返回 true<\9(A ~= B) 为 true。\
>\9大于，如果左边的值大于右边的值，返回 true，\
否则返回 false\9(A > B) 为 false。\
<\9小于，如果左边的值大于右边的值，返回 false，\
否则返回 true\9(A < B) 为 true。\
>=\9大于等于，如果左边的值大于等于右边的值，返回 true，\
否则返回 false\9(A >= B) 返回 false。\
<=\9小于等于， 如果左边的值小于等于右边的值，返回 true，\
否则返回 false\9(A <= B) 返回 true。\
\
逻辑运算符\
下表列出了 Lua 语言中的常用逻辑运算符，设定 A 的值为 true，B 的值为 false：\
\
and\9逻辑与操作符。\
如果两边的操作都为 true 则条件为 true。\
(A and B) 为 false。\
or\9逻辑或操作符。\
如果两边的操作任一一个为 true 则条件为 true。\
(A or B) 为 true。\
not\9逻辑非操作符。\
与逻辑运算结果相反，如果条件为 true，逻辑非为 false。\
not(A and B) 为 true。\
\
其他运算符\
下表列出了 Lua 语言中的连接运算符与计算表或字符串长度的运算符：\
\
..\9连接两个字符串\9a..b\
#\9一元运算符，返回字符串或表的长度。\
\
运算符优先级\
从高到低的顺序：\
\
\
^\
not    - (unary)\
*      /\
+      -\
..\
<      >      <=     >=     ~=     ==\
and\
or" ;
      --26
      "字符串或串(String)是由数字、字母、下划线组成的一串字符。\
Lua 语言中字符串可以使用以下三种方式来表示：\
\
单引号间的一串字符。\
双引号间的一串字符。\
[[和]]间的一串字符。\
\
以上三种方式的字符串实例如下：\
\
string1 = \"ALua手册\"\
print(\"\\\"字符串 1 是\\\"\",string1)\
--字符串 1 是\9ALua手册\
string2 = 'androlua.cn'\
--字符串 2 是\9androlua.cn\
print(\"字符串 2 是\",string2)\
string3 = [[\"Lua 教程\"]]\
print(\"字符串 3 是\",string3)\
--字符串 3 是\9\"Lua 教程\"" ;
      --27
      "数组，就是相同数据类型的元素按一定顺序排列的集合，可以是一维数组和多维数组。\
Lua 数组的索引键值可以使用整数表示，数组的大小不是固定的。" ;
      --28
      "一维数组是最简单的数组，其逻辑结构是线性表。一维数组可以用for循环出数组中的元素，如下实例：\
\
array = {\"Lua\", \"Tutorial\"}\
for i= 0, 2 do\
   print(array[i])\
end\
\
以上代码执行输出结果为：\
\
nil\
Lua\
Tutorial\
\
正如你所看到的，我们可以使用整数索引来访问数组元素，如果知道的索引没有值则返回nil。\
在 Lua 索引值是以 1 为起始，但你也可以指定 0 开始。" ;
      --29
      "迭代器（iterator）是一种对象，它能够用来遍历标准模板库容器中的部分或全部元素，每个迭代器对象代表容器中的确定的地址\
\
在Lua中迭代器是一种支持指针类型的结构，它可以遍历集合的每一个元素。" ;
      --30
      "泛型 for 在自己内部保存迭代函数，实际上它保存三个值：迭代函数、状态常量、控制变量。\
\
泛型 for 迭代器提供了集合的 key/value 对，语法格式如下：\
\
for k, v in pairs(t) do\
    print(k, v)\
end\
上面代码中，k, v为变量列表；pair(t)为表达式列表。\
\
查看以下实例:\
\
array = {\"Lua\", \"Tutorial\"}\
\
for key,value in ipairs(array)\
do\
   print(key, value)\
end\
以上代码执行输出结果为：\
\
Lua\
Tutorial\
\
以上实例中我们使用了 Lua 默认提供的迭代函数 ipairs。\
\
下面我们看看范性for的执行过程：\
\
首先，初始化，计算in后面表达式的值，表达式应该返回范性for需要的三个值：迭代函数、状态常量、控制变量；与多值赋值一样，如果表达式返回的结果个数不足三个会自动用nil补足，多出部分会被忽略。\
第二，将状态常量和控制变量作为参数调用迭代函数（注意：对于for结构来说，状态常量没有用处，仅仅在初始化时获取他的值并传递给迭代函数）。\
第三，将迭代函数返回的值赋给变量列表。\
第四，如果返回的第一个值为nil循环结束，否则执行循环体。\
第五，回到第二步再次调用迭代函数\
。在Lua中我们常常使用函数来描述迭代器，每次调用该函数就返回集合的下一个元素。Lua 的迭代器包含以下两种类型：\
\
1，无状态的迭代器\
2，多状态的迭代器" ;
      --31
      "无状态的迭代器是指不保留任何状态的迭代器，因此在循环中我们可以利用无状态迭代器避免创建闭包花费额外的代价。\
\
每一次迭代，迭代函数都是用两个变量（状态常量和控制变量）的值作为参数被调用，一个无状态的迭代器只利用这两个值可以获取下一个元素。\
\
这种无状态迭代器的典型的简单的例子是ipairs，他遍历数组的每一个元素。\
\
以下实例我们使用了一个简单的函数来实现迭代器，实现 数字 n 的平方：\
\
function square(iteratorMaxCount,currentNumber)\
   if currentNumber<iteratorMaxCount\
   then\
      currentNumber = currentNumber+1\
   return currentNumber, currentNumber*currentNumber\
   end\
end\
\
for i,n in square,3,0\
do\
   print(i,n)\
end\
\
以上实例输出结果为：\
\
1\
4\
9\
\
迭代的状态包括被遍历的表（循环过程中不会改变的状态常量）和当前的索引下标（控制变量），ipairs和迭代函数都很简单，我们在Lua中可以这样实现：\
\
function iter (a, i)\
    i = i + 1\
    local v = a[i]\
    if v then\
       return i, v\
    end\
end\
\
function ipairs (a)\
    return iter, a, 0\
end\
\
当Lua调用ipairs(a)开始循环时，他获取三个值：迭代函数iter、状态常量a、控制变量初始值0；然后Lua调用iter(a,0)返回1,a[1]（除非a[1]=nil）；第二次迭代调用iter(a,1)返回2,a[2]……直到第一个nil元素。" ;
      --32
      "很多情况下，迭代器需要保存多个状态信息而不是简单的状态常量和控制变量，最简单的方法是使用闭包，还有一种方法就是将所有的状态信息封装到table内，将table作为迭代器的状态常量，因为这种情况下可以将所有的信息存放在table内，所以迭代函数通常不需要第二个参数。\
\
以下实例我们创建了自己的迭代器：\
\
array = {\"Lua\", \"Tutorial\"}\
\
function elementIterator (collection)\
   local index = 0\
   local count = #collection\
   -- 闭包函数\
   return function ()\
      index = index + 1\
      if index <= count\
      then\
         --  返回迭代器的当前元素\
         return collection[index]\
      end\
   end\
end\
\
for element in elementIterator(array)\
do\
   print(element)\
end\
\
以上实例输出结果为：\
\
Lua\
Tutorial\
\
以上实例中我们可以看到，elementIterator 内使用了闭包函数，实现计算集合大小并输出各个元素。" ;
      --33
      "Lua I/O 库用于读取和处理文件。分为简单模式（和C一样）、完全模式。\
\
简单模式（simple model）拥有一个当前输入文件和一个当前输出文件，并且提供针对这些文件相关的操作。\
完全模式（complete model） 使用外部的文件句柄来实现。它以一种面对对象的形式，将所有的文件操作定义为文件句柄的方法\
简单模式在做一些简单的文件操作时较为合适。但是在进行一些高级的文件操作的时候，简单模式就显得力不从心。例如同时读取多个文件这样的操作，使用完全模式则较为合适。\
\
打开文件操作语句如下：\
\
file = io.open (filename , mode)\
mode 的值有：\
\
\"r\"\9以只读方式打开文件，该文件必须存在。\
\"w\"\9打开只写文件，若文件存在则文件长度清为0，即该文件内容会消失。若文件不存在则建立该文件。\
\"a\"\9以附加的方式打开只写文件。若文件不存在，则会建立该文件，如果文件存在，写入的数据会被加到文件尾，即文件原先的内容会被保留。（EOF符保留）\
\"r+\"\9以可读写方式打开文件，该文件必须存在。\
\"w+\"\9打开可读写文件，若文件存在则文件长度清为零，即该文件内容会消失。若文件不存在则建立该文件。\
\"a+\"\9与a类似，但此文件可读可写\
\"b\"\9二进制模式，如果文件是二进制文件，可以加上b" ;
      --34
      "简单模式使用标准的 I/O 或使用一个当前输入文件和一个当前输出文件。\
\
以下为 file.lua 文件代码，操作的文件为test.lua(如果没有你需要创建该文件)，代码如下：\
\
-- 以只读方式打开文件\
file = io.open(\"test.lua\", \"r\")\
\
-- 设置默认输入文件为 test.lua\
io.input(file)\
\
-- 输出文件第一行\
print(io.read())\
\
-- 关闭打开的文件\
io.close(file)\
\
-- 以附加的方式打开只写文件\
file = io.open(\"test.lua\", \"a\")\
\
-- 设置默认输出文件为 test.lua\
io.output(file)\
\
-- 在文件最后一行添加 Lua 注释\
io.write(\"--  test.lua 文件末尾注释\")\
\
-- 关闭打开的文件\
io.close(file)\
执行以上代码，你会发现，输出了 test.ua 文件的第一行信息，并在该文件最后一行添加了 lua 的注释。如我这边输出的是：\
\
-- test.lua 文件\
在以上实例中我们使用了 io.\"x\" 方法，其中 io.read() 中我们没有带参数，参数可以是下表中的一个：\
\
\"*n\"\9读取一个数字并返回它。例：file.read(\"*n\")\
\"*a\"\9从当前位置读取整个文件。例：file.read(\"*a\")\
\"*l\"（默认）\9读取下一行，在文件尾 (EOF) 处返回 nil。例：file.read(\"*l\")\
number\9返回一个指定字符个数的字符串，或在 EOF 时返回 nil。例：file.read(5)\
其他的 io 方法有：\
\
io.tmpfile():返回一个临时文件句柄，该文件以更新模式打开，程序结束时自动删除\
\
io.type(file): 检测obj是否一个可用的文件句柄\
\
io.flush(): 向文件写入缓冲中的所有数据\
\
io.lines(optional file name): 返回一个迭代函数,每次调用将获得文件中的一行内容,当到文件尾时，将返回nil,但不关闭文件" ;
      --35
      "通常我们需要在同一时间处理多个文件。我们需要使用 file:function_name 来代替 io.function_name 方法。以下实例演示了如同同时处理同一个文件:\
\
-- 以只读方式打开文件\
file = io.open(\"test.lua\", \"r\")\
\
-- 输出文件第一行\
print(file:read())\
\
-- 关闭打开的文件\
file:close()\
\
-- 以附加的方式打开只写文件\
file = io.open(\"test.lua\", \"a\")\
\
-- 在文件最后一行添加 Lua 注释\
file:write(\"--test\")\
\
-- 关闭打开的文件\
file:close()\
执行以上代码，你会发现，输出了 test.ua 文件的第一行信息，并在该文件最后一行添加了 lua 的注释。如我这边输出的是：\
\
-- test.lua 文件\
read 的参数与简单模式一致。" ;
      --36
      "file:seek(optional whence, optional offset): 设置和获取当前文件位置,成功则返回最终的文件位置(按字节),失败则返回nil加错误信息。参数 whence 值可以是:\
\
\"set\": 从文件头开始\
\"cur\": 从当前位置开始[默认]\
\"end\": 从文件尾开始\
offset:默认为0\
不带参数file:seek()则返回当前位置,file:seek(\"set\")则定位到文件头,file:seek(\"end\")则定位到文件尾并返回文件大小\
file:flush(): 向文件写入缓冲中的所有数据\
\
io.lines(optional file name): 打开指定的文件filename为读模式并返回一个迭代函数,每次调用将获得文件中的一行内容,当到文件尾时，将返回nil,并自动关闭文件。\
若不带参数时io.lines() <=> io.input():lines(); 读取默认输入设备的内容，但结束时不关闭文件,如\
\
for line in io.lines(\"main.lua\") do\
\
　　print(line)\
\
　　end\
\
以下实例使用了 seek 方法，定位到文件倒数第 25 个位置并使用 read 方法的 *a 参数，即从当期位置(倒数第 25 个位置)读取整个文件。\
\
-- 以只读方式打开文件\
file = io.open(\"test.lua\", \"r\")\
\
file:seek(\"end\",-25)\
print(file:read(\"*a\"))\
\
-- 关闭打开的文件\
file:close()\
我这边输出的结果是：\
\
st.lua 文件末尾--test" ;
      --37
      "程序运行中错误处理是必要的，在我们进行文件操作，数据转移及web service 调用过程中都会出现不可预期的错误。如果不注重错误信息的处理，就会照成信息泄露，程序无法运行等情况。\
任何程序语言中，都需要错误处理。错误类型有：\
1，语法错误\
2，运行错误" ;
      --38
      "语法错误通常是由于对程序的组件（如运算符、表达式）使用不当引起的。一个简单的实例如下：\
-- test.lua 文件\
a == 2\
以上代码执行结果为：\
\
lua: test.lua:2: syntax error near '=='\
\
正如你所看到的，以上出现了语法错误，一个 \"=\" 号跟两个 \"=\" 号是有区别的。一个 \"=\" 是赋值表达式两个 \"=\" 是比较运算。\
另外一个实例:\
\
for a= 1,10\
   print(a)\
end\
\
执行以上程序会出现如下错误：\
\
lua: test2.lua:2: 'do' expected near 'print'\
\
语法错误比程序运行错误更简单，运行错误无法定位具体错误，而语法错误我们可以很快的解决，如以上实例我们只要在for语句下添加 do 即可：\
\
for a= 1,10\
do\
   print(a)\
end" ;
      --39
      "运行错误是程序可以正常执行，但是会输出报错信息。如下实例由于参数输入错误，程序执行时报错：\
\
function add(a,b)\
   return a+b\
end\
\
add(10)\
\
当我们编译运行以下代码时，编译是可以成功的，但在运行的时候会产生如下错误：\
\
lua: test2.lua:2: attempt to perform arithmetic on local 'b' (a nil value)\
stack traceback:\
    test2.lua:2: in function 'add'\
    test2.lua:5: in main chunk\
    [C]: ?\
\
以下报错信息是由于程序缺少 b 参数引起的。" ;
      --40
      "我们可以使用两个函数：assert 和 error 来处理错误。实例如下：\
\
local function add(a,b)\
   assert(type(a) == \"number\", \"a 不是一个数字\")\
   assert(type(b) == \"number\", \"b 不是一个数字\")\
   return a+b\
end\
add(10)\
\
执行以上程序会出现如下错误：\
\
lua: test.lua:3: b 不是一个数字\
stack traceback:\
    [C]: in function 'assert'\
    test.lua:3: in local 'add'\
    test.lua:6: in main chunk\
    [C]: in ?\
\
实例中assert首先检查第一个参数，若没问题，assert不做任何事情；否则，assert以第二个参数作为错误信息抛出。" ;
      --41
      "语法格式：\
\
error (message [, level])\
\
功能：终止正在执行的函数，并返回message的内容作为错误信息(error函数永远都不会返回)\
通常情况下，error会附加一些错误位置的信息到message头部。\
Level参数指示获得错误的位置:\
Level=1[默认]：为调用error位置(文件+行号)\
Level=2：指出哪个调用error的函数的函数\
Level=0:不添加错误位置信息" ;
      --42
      "Lua中处理错误，可以使用函数pcall（protected call）来包装需要执行的代码。\
pcall接收一个函数和要传递个后者的参数，并执行，执行结果：有错误、无错误；返回值true或者或false, errorinfo。\
语法格式如下\
\
if pcall(function_name, ….) then\
-- 没有错误\
else\
-- 一些错误\
end\
\
简单实例：\
\
> =pcall(function(i) print(i) end, 33)\
33\
true\
\
> =pcall(function(i) print(i) error('error..') end, 33)\
33\
false        stdin:1: error..\
> function f() return false,2 end\
> if f() then print '1' else print '0' end\
0\
\
pcall以一种\"保护模式\"来调用第一个参数，因此pcall可以捕获函数执行中的任何错误。\
通常在错误发生时，希望落得更多的调试信息，而不只是发生错误的位置。但pcall返回时，它已经销毁了调用桟的部分内容。\
Lua提供了xpcall函数，xpcall接收第二个参数——一个错误处理函数，当错误发生时，Lua会在调用桟展看（unwind）前调用错误处理函数，于是就可以在这个函数中使用debug库来获取关于错误的额外信息了。\
debug库提供了两个通用的错误处理函数:\
\
debug.debug：提供一个Lua提示符，让用户来价差错误的原因\
debug.traceback：根据调用桟来构建一个扩展的错误消息\
\
>=xpcall(function(i) print(i) error('error..') end, function() print(debug.traceback()) end, 33) 33 stack traceback: stdin:1: in function [C]: in function 'error' stdin:1: in function [C]: in function 'xpcall' stdin:1: in main chunk [C]: in ? false nil\
\
xpcall 使用实例 2:\
\
function myfunction ()\
   n = n/nil\
end\
\
function myerrorhandler( err )\
   print( \"ERROR:\", err )\
end\
\
status = xpcall( myfunction, myerrorhandler )\
print( status)\
\
执行以上程序会出现如下错误：\
\
ERROR:    test2.lua:2: attempt to perform arithmetic on global 'n' (a nil value)\
false" ;
      --43
      "Lua 提供了 debug 库用于提供创建我们自定义调速器的功能。Lua 本身并未有内置的调速器，但很多开发者共享了他们的 Lua 调速器代码。\
Lua 中 debug 库包含以下函数：\
\
sethook ([thread,] hook, mask [, count]):\
\
1.debug():\
进入一个用户交互模式，运行用户输入的每个字符串。 使用简单的命令以及其它调试设置，用户可以检阅全局变量和局部变量， 改变变量的值，计算一些表达式，等等。\
输入一行仅包含 cont 的字符串将结束这个函数， 这样调用者就可以继续向下运行。\
\
2.getfenv(object):\
返回对象的环境变量。\
\
3.gethook(optional thread):\
返回三个表示线程钩子设置的值： 当前钩子函数，当前钩子掩码，当前钩子计数\
\
4.getinfo ([thread,] f [, what]):\
返回关于一个函数信息的表。 你可以直接提供该函数， 也可以用一个数字 f 表示该函数。 数字 f 表示运行在指定线程的调用栈对应层次上的函数： 0 层表示当前函数（getinfo 自身）； 1 层表示调用 getinfo 的函数 （除非是尾调用，这种情况不计入栈）；等等。 如果 f 是一个比活动函数数量还大的数字， getinfo 返回 nil。\
\
5.debug.getlocal ([thread,] f, local):\
此函数返回在栈的 f 层处函数的索引为 local 的局部变量 的名字和值。 这个函数不仅用于访问显式定义的局部变量，也包括形参、临时变量等。\
\
6.getmetatable(value):\
把给定索引指向的值的元表压入堆栈。如果索引无效，或是这个值没有元表，函数将返回 0 并且不会向栈上压任何东西。\
\
7.getregistry():\
返回注册表表，这是一个预定义出来的表， 可以用来保存任何 C 代码想保存的 Lua 值。\
\
8.getupvalue (f, up)\
此函数返回函数 f 的第 up 个上值的名字和值。 如果该函数没有那个上值，返回 nil 。\
以 '(' （开括号）打头的变量名表示没有名字的变量 （去除了调试信息的代码块）。\
\
10.将一个函数作为钩子函数设入。 字符串 mask 以及数字 count 决定了钩子将在何时调用。 掩码是由下列字符组合成的字符串，每个字符有其含义：\
'c': 每当 Lua 调用一个函数时，调用钩子；\
'r': 每当 Lua 从一个函数内返回时，调用钩子；\
'l': 每当 Lua 进入新的一行时，调用钩子。\
\
11.setlocal ([thread,] level, local, value):\
这个函数将 value 赋给 栈上第 level 层函数的第 local 个局部变量。 如果没有那个变量，函数返回 nil 。 如果 level 越界，抛出一个错误。\
\
12.setmetatable (value, table):\
将 value 的元表设为 table （可以是 nil）。 返回 value。\
\
13.setupvalue (f, up, value):\
这个函数将 value 设为函数 f 的第 up 个上值。 如果函数没有那个上值，返回 nil 否则，返回该上值的名字。\
\
14.traceback ([thread,] [message [, level]]):\
如果 message 有，且不是字符串或 nil， 函数不做任何处理直接返回 message。 否则，它返回调用栈的栈回溯信息。 字符串可选项 message 被添加在栈回溯信息的开头。 数字可选项 level 指明从栈的哪一层开始回溯 （默认为 1 ，即调用 traceback 的那里）。\
\
上表列出了我们常用的调试函数，接下来我们可以看些简单的例子：\
\
function myfunction ()\
print(debug.traceback(\"Stack trace\"))\
print(debug.getinfo(1))\
print(\"Stack trace end\")\
    return 10\
end\
myfunction ()\
print(debug.getinfo(1))\
\
执行以上代码输出结果为：\
\
Stack trace\
stack traceback:\
    test2.lua:2: in function 'myfunction'\
    test2.lua:8: in main chunk\
    [C]: ?\
table: 0054C6C8\
Stack trace end\
\
在以实例中，我们使用到了 debug 库的 traceback 和 getinfo 函数， getinfo 函数用于返回函数信息的表。 " ;
      --44
      "我们经常需要调试函数的内的局部变量。我们可以使用 getupvalue 函数来设置这些局部变量。实例如下：\
\
function newCounter ()\
  local n = 0\
  local k = 0\
  return function ()\
    k = n\
    n = n + 1\
    return n\
    end\
end\
\
counter = newCounter ()\
print(counter())\
print(counter())\
\
local i = 1\
\
repeat\
  name, val = debug.getupvalue(counter, i)\
  if name then\
    print (\"index\", i, name, \"=\", val)\
    if(name == \"n\") then\
        debug.setupvalue (counter,2,10)\
    end\
    i = i + 1\
  end -- if\
until not name\
\
print(counter())\
\
执行以上代码输出结果为：\
\
1\
2\
index    1    k    =    1\
index    2    n    =    2\
11\
\
在以上实例中，计数器在每次调用时都会自增1。实例中我们使用了 getupvalue 函数查看局部变量的当前状态。我们可以设置局部变量为新值。实例中，在设置前 n 的值为 2,使用 setupvalue 函数将其设置为 10。现在我们调用函数，执行后输出为 11 而不是 3。" ;
      --45
      "1，命令行调试\
2，图形界面调试\
\
命令行调试器有：RemDebug、clidebugger、ctrace、xdbLua、LuaInterface - Debugger、Rldb、ModDebug。\
图形界调试器有：SciTE、Decoda、ZeroBrane Studio、akdebugger、luaedit。" ;
      --46
      "Lua 采用了自动内存管理。 这意味着你不用操心新创建的对象需要的内存如何分配出来， 也不用考虑在对象不再被使用后怎样释放它们所占用的内存。\
Lua 运行了一个垃圾收集器来收集所有死对象 （即在 Lua 中不可能再访问到的对象）来完成自动内存管理的工作。 Lua 中所有用到的内存，如：字符串、表、用户数据、函数、线程、 内部结构等，都服从自动管理。\
Lua 实现了一个增量标记-扫描收集器。 它使用这两个数字来控制垃圾收集循环： 垃圾收集器间歇率和垃圾收集器步进倍率。 这两个数字都使用百分数为单位 （例如：值 100 在内部表示 1 ）。\
垃圾收集器间歇率控制着收集器需要在开启新的循环前要等待多久。 增大这个值会减少收集器的积极性。 当这个值比 100 小的时候，收集器在开启新的循环前不会有等待。 设置这个值为 200 就会让收集器等到总内存使用量达到 之前的两倍时才开始新的循环。\
垃圾收集器步进倍率控制着收集器运作速度相对于内存分配速度的倍率。 增大这个值不仅会让收集器更加积极，还会增加每个增量步骤的长度。 不要把这个值设得小于 100 ， 那样的话收集器就工作的太慢了以至于永远都干不完一个循环。 默认值是 200 ，这表示收集器以内存分配的\"两倍\"速工作。\
如果你把步进倍率设为一个非常大的数字 （比你的程序可能用到的字节数还大 10% ）， 收集器的行为就像一个 stop-the-world 收集器。 接着你若把间歇率设为 200 ， 收集器的行为就和过去的 Lua 版本一样了： 每次 Lua 使用的内存翻倍时，就做一次完整的收集。" ;
      --47
      "Lua 提供了以下函数collectgarbage ([opt [, arg]])用来控制自动内存管理:\
\
1， collectgarbage(\"collect\"): 做一次完整的垃圾收集循环。通过参数 opt 它提供了一组不同的功能：\
2， collectgarbage(\"count\"): 以 K 字节数为单位返回 Lua 使用的总内存数。 这个值有小数部分，所以只需要乘上 1024 就能得到 Lua 使用的准确字节数（除非溢出）。\
3， collectgarbage(\"restart\"): 重启垃圾收集器的自动运行。\
4， collectgarbage(\"setpause\"): 将 arg 设为收集器的 间歇率 （参见 §2.5）。 返回 间歇率 的前一个值。\
5， collectgarbage(\"setstepmul\"): 返回 步进倍率 的前一个值。\
6， collectgarbage(\"step\"): 单步运行垃圾收集器。 步长\"大小\"由 arg 控制。 传入 0 时，收集器步进（不可分割的）一步。 传入非 0 值， 收集器收集相当于 Lua 分配这些多（K 字节）内存的工作。 如果收集器结束一个循环将返回 true 。\
7， collectgarbage(\"stop\"): 停止垃圾收集器的运行。 在调用重启前，收集器只会因显式的调用运行。\
\
以下演示了一个简单的垃圾回收实例:\
\
mytable = {\"apple\", \"orange\", \"banana\"}\
\
print(collectgarbage(\"count\"))\
\
mytable = nil\
\
print(collectgarbage(\"count\"))\
\
print(collectgarbage(\"collect\"))\
\
print(collectgarbage(\"count\"))\
\
执行以上程序，输出结果如下(注意内存使用的变化)：\
\
20.9560546875\
20.9853515625\
0\
19.4111328125" ;
      --48
      "面向对象编程（Object Oriented Programming，OOP）是一种非常流行的计算机编程架构。\
以下几种编程语言都支持面向对象编程：\
\
C++\
Java\
Objective-C\
Smalltalk\
C#\
Ruby" ;
      --49
      "1， 封装：指能够把一个实体的信息、功能、响应都装入一个单独的对象中的特性。\
2， 继承：继承的方法允许在不改动原程序的基础上对其进行扩充，这样使得原功能得以保存，而新功能也得以扩展。这有利于减少重复编码，提高软件的开发效率。\
3， 多态：同一操作作用于不同的对象，可以有不同的解释，产生不同的执行结果。在运行时，可以通过指向基类的指针，来调用实现派生类中的方法。\
4，抽象：抽象(Abstraction)是简化复杂的现实问题的途径，它可以为具体问题找到最恰当的类定义，并且可以在最恰当的继承级别解释问题。" ;
      --50
      "我们知道，对象由属性和方法组成。LUA中最基本的结构是table，所以需要用table来描述对象的属性。\
lua中的function可以用来表示方法。那么LUA中的类可以通过table + function模拟出来。\
至于继承，可以通过metetable模拟出来（不推荐用，只模拟最基本的对象大部分时间够用了）。\
\
Lua中的表不仅在某种意义上是一种对象。像对象一样，表也有状态（成员变量）；也有与对象的值独立的本性，特别是拥有两个不同值的对象（table）代表两个不同的对象；一个对象在不同的时候也可以有不同的值，但他始终是一个对象；与对象类似，表的生命周期与其由什么创建、在哪创建没有关系。对象有他们的成员函数，表也有：\
\
Account = {balance = 0}\
function Account.withdraw (v)\
    Account.balance = Account.balance - v\
end\
\
这个定义创建了一个新的函数，并且保存在Account对象的withdraw域内，下面我们可以这样调用：\
\
Account.withdraw(100.00)\
\
一个简单实例\
以下简单的类包含了三个属性： area, length 和 breadth，printArea方法用于打印计算结果：\
\
-- Meta class\
Rectangle = {area = 0, length = 0, breadth = 0}\
-- 派生类的方法 new\
function Rectangle:new (o,length,breadth)\
  o = o or {}\
  setmetatable(o, self)\
  self.__index = self\
  self.length = length or 0\
  self.breadth = breadth or 0\
  self.area = length*breadth;\
  return o\
end\
-- 派生类的方法 printArea\
function Rectangle:printArea ()\
  print(\"矩形面积为 \",self.area)\
end\
\
创建对象\
创建对象是位类的实例分配内存的过程。每个类都有属于自己的内存并共享公共数据。\
r = Rectangle:new(nil,10,20)\
\
访问属性\
我们可以使用点号(.)来访问类的属性：\
print(r.length)\
\
访问成员函数\
我们可以使用冒号 : 来访问类的成员函数：\
r:printArea()\
内存在对象初始化时分配。\
\
完整实例\
\
以下我们演示了 Lua 面向对象的完整实例：\
\
-- Meta class\
Shape = {area = 0}\
\
-- 基础类方法 new\
function Shape:new (o,side)\
  o = o or {}\
  setmetatable(o, self)\
  self.__index = self\
  side = side or 0\
  self.area = side*side;\
  return o\
end\
\
-- 基础类方法 printArea\
function Shape:printArea ()\
  print(\"面积为 \",self.area)\
end\
\
-- 创建对象\
myshape = Shape:new(nil,10)\
\
myshape:printArea()\
\
执行以上程序，输出结果为：\
\
面积为     100" ;
      --51
      "继承是指一个对象直接使用另一对象的属性和方法。可用于扩展基础类的属性和方法。\
以下演示了一个简单的继承实例：\
\
 -- Meta class\
Shape = {area = 0}\
-- 基础类方法 new\
function Shape:new (o,side)\
  o = o or {}\
  setmetatable(o, self)\
  self.__index = self\
  side = side or 0\
  self.area = side*side;\
  return o\
end\
-- 基础类方法 printArea\
function Shape:printArea ()\
  print(\"面积为 \",self.area)\
end\
\
接下来的实例，Square 对象继承了 Shape 类:\
\
Square = Shape:new()\
-- Derived class method new\
function Square:new (o,side)\
  o = o or Shape:new(o,side)\
  setmetatable(o, self)\
  self.__index = self\
  return o\
end\
\
完整实例\
以下实例我们继承了一个简单的类，来扩展派生类的方法，派生类中保留了继承类的成员变量和方法：\
\
 -- Meta class\
Shape = {area = 0}\
-- 基础类方法 new\
function Shape:new (o,side)\
  o = o or {}\
  setmetatable(o, self)\
  self.__index = self\
  side = side or 0\
  self.area = side*side;\
  return o\
end\
-- 基础类方法 printArea\
function Shape:printArea ()\
  print(\"面积为 \",self.area)\
end\
\
-- 创建对象\
myshape = Shape:new(nil,10)\
myshape:printArea()\
\
Square = Shape:new()\
-- 派生类方法 new\
function Square:new (o,side)\
  o = o or Shape:new(o,side)\
  setmetatable(o, self)\
  self.__index = self\
  return o\
end\
\
-- 派生类方法 printArea\
function Square:printArea ()\
  print(\"正方形面积为 \",self.area)\
end\
\
-- 创建对象\
mysquare = Square:new(nil,10)\
mysquare:printArea()\
\
Rectangle = Shape:new()\
-- 派生类方法 new\
function Rectangle:new (o,length,breadth)\
  o = o or Shape:new(o)\
  setmetatable(o, self)\
  self.__index = self\
  self.area = length * breadth\
  return o\
end\
\
-- 派生类方法 printArea\
function Rectangle:printArea ()\
  print(\"矩形面积为 \",self.area)\
end\
\
-- 创建对象\
myrectangle = Rectangle:new(nil,10,20)\
myrectangle:printArea()\
\
执行以上代码，输出结果为：\
\
面积为     100\
正方形面积为     100\
矩形面积为     200" ;
      --52
      "Lua 中我们可以重写基础类的函数，在派生类中定义自己的实现方式：\
\
-- 派生类方法 printArea\
function Square:printArea ()\
  print(\"正方形面积 \",self.area)\
end" ;
    },
    用户界面={
      --1
      "--部分常用API\
show:显示\
hide:隐藏\
Elevation:设置阴影\
BgroundDrawable:设置背景\
DisplayHomeAsUpEnabled(boolean):设置是否显示返回图标\
\
\
\
--设置标题\
activity.ActionBar.setTitle('大标题')\
activity.ActionBar.setSubTitle(\"小标题\")\
\
--设置ActionBar背景颜色\
import \"android.graphics.drawable.ColorDrawable\"\
activity.ActionBar.setBackgroundDrawable(ColorDrawable(Color))\
\
--自定义ActionBar标题颜色\
import \"android.text.SpannableString\"\
import \"android.text.style.ForegroundColorSpan\"\
import \"android.text.Spannable\"\
sp = SpannableString(\"标题\")\
sp.setSpan(ForegroundColorSpan(0xff1DA6DD),0,#sp,Spannable.SPAN_EXCLUSIVE_INCLUSIVE)\
activity.ActionBar.setTitle(sp)\
\
--自定义ActionBar布局\
DisplayShowCustomEnabled(true)\
CustomView(loadlayout(layout))\
\
\
--ActionBar返回按钮\
activity.ActionBar.setDisplayHomeAsUpEnabled(true)\
--自定义返回按钮图标\
activity.ActionBar.setHomeAsUpIndicator(drawable)\
\
\
--菜单\
function onCreateOptionsMenu(menu)\
  menu.add(\"菜单1\")\
  menu.add(\"菜单2\")\
  menu.add(\"菜单3\")\
end\
function onOptionsItemSelected(item)\
  print(\"你选择了:\"..item.Title)\
end\
\
\
\
\
\
--Tab导航使用\
import \"android.app.ActionBar$TabListener\"\
actionBar=activity.ActionBar\
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);\
tab = actionBar.newTab().setText(\"Tab1\").setTabListener(TabListener({\
  onTabSelected=function()\
    print\"Tab1\"\
  end}))\
tab2=actionBar.newTab().setText(\"Tab2\").setTabListener(TabListener({\
  onTabSelected=function()\
    print\"Tab2\"\
  end}))\
actionBar.addTab(tab)\
actionBar.addTab(tab2)" ;
      --2
      "--Android中常用的5大布局方式有以下几种：\
--线性布局（LinearLayout）：按照垂直或者水平方向布局的组件。\
--帧布局（FrameLayout）：组件从屏幕左上方布局组件。\
--表格布局（TableLayout）：按照行列方式布局组件。\
--相对布局（RelativeLayout）：相对其它组件的布局方式。\
--绝对布局（AbsoluteLayout）：按照绝对坐标来布局组件。\
\
\
1.线性布局(LinearLayout)\
线性布局是Android开发中最常见的一种布局方式，它是按照垂直或者水平方向来布局，通过orientation属性可以设置线性布局的方向。属性值有垂直（vertical）和水平（horizontal）两种。\
常用的属性：\
orientation：可以设置布局的方向\
gravity:用来控制组件的对齐方式\
layout_weight控制各个控件在布局中的相对大小,layout_weight的属性是一个非负整数值。  \
线性布局会根据该控件layout_weight值与其所处布局中所有控件layout_weight值之和的比值为该控件分配占用的区域\
--[[例如，在水平布局的LinearLayout中有两个Button，这两个Button的layout_weight属性值都为1,那么这两个按钮都会被拉伸到整个屏幕宽度的一半。如果layout_weight指为0，控件会按原大小显示，不会被拉伸.\
对于其余layout_weight属性值大于0的控件，系统将会减去layout_weight属性值为0的控件的宽度或者高度,再用剩余的宽度或高度按相应的比例来分配每一个控件显示的宽度或高度]]\
\
\
2.帧布局(FrameLayout)\
帧布局是从屏幕的左上角（0,0）坐标开始布局，多个组件层叠排列，第一个添加的组件放到最底层，最后添加到框架中的视图显示在最上面。上一层的会覆盖下一层的控件。\
\
\
3.表格布局（TableLayout）\
表格布局是一个ViewGroup以表格显示它的子视图（view）元素，即行和列标识一个视图的位置。\
表格布局常用的属性如下：\
collapseColumns：隐藏指定的列\
shrinkColumns：收缩指定的列以适合屏幕，不会挤出屏幕\
stretchColumns：尽量把指定的列填充空白部分\
layout_column:控件放在指定的列\
layout_span:该控件所跨越的列数\
\
\
4.相对布局（RelativeLayout）\
相对布局是按照组件之间的相对位置来布局，比如在某个组件的左边，右边，上面和下面等。\
\
\
5.绝对布局(AbsoluteLayout)\
采用坐标轴的方式定位组件，左上角是（0，0）点，往右x轴递增，往下Y轴递增,组件定位属性为layout_x 和layout_y来确定坐标。" ;
      --3
      "--Button(按钮控件)、TextView(文本控件)、EditText(编辑框控件)\
\
常用API:\
id.setText(\"文本\")--设置控件文本\
id.getText()--获取控件文本\
id.setWidth(300)--设置控件宽度\
id.setHeight(300)--设置控件高度\
\
\
--点击事件\
id.onClick=function()\
print\"你触发了点击事件\"\
end\
\
--长按事件\
id.onLongClick=function()\
print\"你触发了长按事件\"\
end\
\
\
\
--图片控件(ImageView与ImageButton)\
--设置图片\
--布局表中用src属性就可以，如:src=图片路径,\
\
--动态设置\
id.setImageBitmap(loadbitmap(图片路径))\
--设置Drawable对象\
import \"android.graphics.drawable.BitmapDrawable\"\
id.setImageDrawable(BitmapDrawable(loadbitmap(图片路径)))\
\
--缩放，scaleType\
--字段\
CENTER    --按原来size居中显示，长/宽超过View的长/宽，截取图片的居中部分显示 \13\
CENTER_CROP    --按比例扩大图片的size居中显示，使图片长(宽)等于或大于View的长(宽) \13\
CENTER_INSIDE  --完整居中显示，按比例缩小使图片长/宽等于或小于View的长/宽 \13\
FIT_CENTER     --按比例扩大/缩小到View的宽度，居中显示 \13\
FIT_END        --按比例扩大/缩小到View的宽度，显示在View的下部分位置 \13\
FIT_START      --按比例扩大/缩小到View的宽度，显示在View的上部分位置 \13\
FIT_XY         --不按比例扩大/缩小到View的大小显示 \13\
MATRIX         --用矩阵来绘制，动态缩小放大图片来显示。 \13\
\
\
--点击与长按事件同上" ;
      --4
      "--CheckBox(复选框),Switch(开关控件),ToggleButton(切换按钮)\
--直接判断是否选中然后执行相应事件即可\
--判断API\
check.isSelected()--返回布尔值\
\
\
--RadioButton(单选按钮)与RadioGroup\
--将RadioButton的父布局设定为RadioGroup然后绑定下面的监听即可\
rp.setOnCheckedChangeListener{\
  onCheckedChanged=function(g,c)\
  l=g.findViewById(c)\
  print(l.Text)\
  end}" ;
      --5
      "--绑定监听\
seekbar.setOnSeekBarChangeListener{\
onStartTrackingTouch=function()\
--开始拖动\
end,\
onStopTrackingTouch=function()\
--停止拖动\
end,\
onProgressChanged=function()\
--状态改变\
end}\
\
--部分API\
Progress--当前进度\
Max--最大进度" ;
      --6
      "--超大号圆形风格\
style=\"?android:attr/progressBarStyleLarge\"\
--小号风格\
style=\"?android:attr/progressBarStyleSmall\"\
--标题型风格\
style=\"?android:attr/progressBarStyleSmallTitle\"\
--长形进度条\
style=\"?android:attr/progressBarStyleHorizontal\"\
\
--部分API\
max --最大进度值\
progress --设置进度值\
secondaryProgress=\"70\" --初始化的底层第二个进度值\
\
id.incrementProgressBy(5)\
--ProgressBar进度值增加5\
id.incrementProgressBy(-5)\
--ProgressBar进度值减少5\
id.incrementSecondaryProgressBy(5)\
--ProgressBar背后的第二个进度条 进度值增加5\
id.incrementSecondaryProgressBy(-5)\
--ProgressBar背后的第二个进度条 进度值减少5 " ;
      --7
      "--适配器控件主要包括(ListView,GridView,Spinner,ExpandableList等)\
\
--想要动态为此类控件添加项目就必须得要依靠适配器！\
--适配器使用\
--AarrayAdapter(简单适配器)\
--创建项目数组\
数据={}\
--添加项目数组\
for i=1,100 do\
table.insert(数据,tostring(i))\
end\
--创建适配器\
array_adp=ArrayAdapter(activity,android.R.layout.simple_list_item_1,String(数据))\
--设置适配器\
lv.setAdapter(array_adp)\
\
\
--LuaAdapter(Lua适配器)\
--创建自定义项目视图\
item={\
  LinearLayout,\
  orientation=\"vertical\",\
    layout_width=\"fill\",\
   {\
    TextView,\
    id=\"text\",\
    layout_margin=\"15dp\",\
    layout_width=\"fill\"\
  },\
}\
--创建项目数组\
data={}\
--创建适配器\
adp=LuaAdapter(activity,data,item)\
--添加数据\
for n=1,100 do\
  table.insert(data,{\
    text={\
      Text=tostring(n),          \
    },    \
  })\
end\
--设置适配器\
lv.Adapter=adp\
\
\
--以上的适配器ListView、Spinner与GridView等控件通用\
\
--那么ExpandableListView(折叠列表)怎么办呢？\
--别怕，安卓系统还提供了一个ArrayExpandableListAdapter来给我们使用，可以简单的适配ExpandableListView，下面给出实例\
\
ns={\
  \"Widget\",\"Check view\",\"Adapter view\",\"Advanced Widget\",\"Layout\",\"Advanced Layout\",\
}\
\
wds={\
  {\"Button\",\"EditText\",\"TextView\",\
    \"ImageButton\",\"ImageView\"},\
  {\"CheckBox\",\"RadioButton\",\"ToggleButton\",\"Switch\"},\
  {\"ListView\",\"ExpandableListView\",\"Spinner\"},\
  {\"SeekBar\",\"ProgressBar\",\"RatingBar\",\
    \"DatePicker\",\"TimePicker\",\"NumberPicker\"},\
  {\"LinearLayout\",\"AbsoluteLayout\",\"FrameLayout\"},\
  {\"RadioGroup\",\"GridLayout\",\
    \"ScrollView\",\"HorizontalScrollView\"},\
}\
\
\
mAdapter=ArrayExpandableListAdapter(activity)\
for k,v in ipairs(ns) do\
  mAdapter.add(v,wds[k])\
end\
el.setAdapter(mAdapter)\
--这样就实现ExpandableListView项目的适配了\
\
\
\
\
--当然AdapterView的事件响应也是与普通控件不同的。\
\
--ListView与GridView的单击与长按事件\
--项目被单击\
id.onItemClick=function(l,v,p,i)\
print(v.Text)\
return true\
end\
--项目被长按\
id.onItemLongClick=function(l,v,p,i)\
print(v.Text)\
return true\
end\
\
\
--Spinner的项目单击事件\
id.onItemSelected=function(l,v,p,i) \
print(v.Text)\
end\
\
--ExpandableListView的父项目与子项目单击事件\
id.onGroupClick=function(l,v,p,s)\
print(v.Text..\":GroupClick\")\
end\
\
id.onChildClick=function(l,v,g,c)\
print(v.Text..\":ChildClick\")\
end" ;
      --8
      "--常用API\
id.loadUrl(\"http://www.androlua.cn\")--加载网页\
id.loadUrl(\"file:///storage/sdcard0/index.html\")--加载本地文件\
id.getTitle()--获取网页标题\
id.getUrl()--获取当前Url\
id.requestFocusFromTouch()--设置支持获取手势焦点\
id.getSettings().setJavaScriptEnabled(true)--设置支持JS\
id.setPluginsEnabled(true)--支持插件\
id.setUseWideViewPort(false)--调整图片自适应\
id.getSettings().setSupportZoom(true)--支持缩放\
id.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN)--支持重新布局\
id.supportMultipleWindows()--设置多窗口\
id.stopLoading()--停止加载网页\
\
\
--状态监听\
id.setWebViewClient{\
shouldOverrideUrlLoading=function(view,url)\
--Url即将跳转\
 end,\
onPageStarted=function(view,url,favicon)\
--网页加载\
end,\
onPageFinished=function(view,url)\
--网页加载完成\
end}" ;
      --9
      "--适配数据\
arr={\"Rain\",\"Rain1\",\"Rain2\"};\
arrayAdapter=LuaArrayAdapter(activity,{TextView,padding=\"10dp\",textSize=\"18sp\",layout_width=\"fill\",textColor=\"#ff000000\"}, String(arr))\
actw.setAdapter(arrayAdapter)\
\
Threshold=1--设置输入几个字符后才能出现提示" ;
      --10
      "--时间改变监听器\
import \"android.widget.TimePicker$OnTimeChangedListener\"\
id.setOnTimeChangedListener{\
  onTimeChanged=function(view,时,分)\
    print(时,分)\
  end}\
\
--部分API\
时=id.getCurrentHour()--获取小时\
分=id.getCurrentMinute()--获取分钟\
id.setIs24HourView(Boolean(true))--设置24小时制" ;
      --11
      "id=dp\
日=id.getDayOfMonth()--获取选择的天数\
月=id.getMonth ()--获取选择的月份\
年=id.getYear()--获取选择的年份\
id.updateDate(2016,1,1)--更新日期\
print(年,月,日)" ;
      --12
      "setMinValue(0)--设置最小值\
setMaxValue(100)--设置最大值\
setValue(50)--设置当前值\
getValue()--获取选择的值\
OnValueChangedListener--数值改变监听器" ;
      --13
      "--常用API\
.setTitle(\"标题\")--设置标题\
.setMessage(\"设置消息\")--设置消息\
.setView(loadlayout(layout))--设置自定义视图\
.setPositiveButton(\"积极\",{onClick=function() end})--设置积极按钮\
.setNeutralButton(\"中立\",nil)--设置中立按钮\
.setNegativeButton(\"否认\",nil)--设置否认按钮\
\
\
\
\
--普通对话框\
AlertDialog.Builder(this)\
.setTitle(\"标题\")\
.setMessage(\"消息\")\
.setPositiveButton(\"积极\",{onClick=function(v) print\"点击了积极按钮\"end})\
.setNeutralButton(\"中立\",nil)\
.setNegativeButton(\"否认\",nil)\
.show()\
\
\
\
\
--输入对话框\
InputLayout={\
  LinearLayout;\
  orientation=\"vertical\";\
  Focusable=true,\
  FocusableInTouchMode=true,\
  {\
    TextView;\
    id=\"Prompt\",\
    textSize=\"15sp\",\
    layout_marginTop=\"10dp\";\
    layout_marginLeft=\"3dp\",\
    layout_width=\"80%w\";\
    layout_gravity=\"center\",\
    text=\"输入:\";\
  };\
  {\
    EditText;\
    hint=\"输入\";\
    layout_marginTop=\"5dp\";\
    layout_width=\"80%w\";\
    layout_gravity=\"center\",\
    id=\"edit\";\
  };\
};\
\
AlertDialog.Builder(this)\
.setTitle(\"标题\")\
.setView(loadlayout(InputLayout))\
.setPositiveButton(\"确定\",{onClick=function(v) print(edit.Text)end})\
.setNegativeButton(\"取消\",nil)\
.show()\
import \"android.view.View$OnFocusChangeListener\"\
edit.setOnFocusChangeListener(OnFocusChangeListener{ \
 onFocusChange=function(v,hasFocus)\
if hasFocus then\
Prompt.setTextColor(0xFD009688)\
end\
end})\
\
\
\
--下载文件对话框\
Download_layout={\
  LinearLayout;\
  orientation=\"vertical\";\
  id=\"Download_father_layout\",\
  {\
    TextView;\
    id=\"linkhint\",\
    layout_marginTop=\"10dp\";\
    text=\"下载链接\",\
    layout_width=\"80%w\";\
    textColor=WidgetColors,\
    layout_gravity=\"center\";\
  };\
  {\
    EditText;\
    id=\"linkedit\",\
    layout_width=\"80%w\";\
    layout_gravity=\"center\";   \
  };\
  {\
    TextView;\
    id=\"pathhint\",\
    text=\"下载路径\",\
    layout_width=\"80%w\";\
    textColor=WidgetColors,\
    layout_marginTop=\"10dp\";\
    layout_gravity=\"center\";\
  };\
  {\
    EditText;\
    id=\"pathedit\",\
    layout_width=\"80%w\";\
    layout_gravity=\"center\";\
  };\
};\
\
AlertDialog.Builder(this)\
.setTitle(\"下载文件\")\
.setView(loadlayout(Download_layout))\
.setPositiveButton(\"下载\",{onClick=function(v)\
  end})\
.setNegativeButton(\"取消\",nil)\
.show()\
\
\
\
\
\
\
\
--列表对话框\
items={}\
for i=1,5 do\
table.insert(items,\"项目\"..tostring(i))\
end\
AlertDialog.Builder(this)\
.setTitle(\"列表对话框\")\
.setItems(items,{onClick=function(l,v) print(items[v+1])end})\
.show()\
\
\
--单选对话框\
单选列表={}\
for i=1,5 do\
table.insert(单选列表,\"单选项目\"..tostring(i))\
end\
local 单选对话框=AlertDialog.Builder(this)\
.setTitle(\"列表对话框\")\
.setSingleChoiceItems(单选列表,-1,{onClick=function(v,p)print(单选列表[p+1])end})\
单选对话框.show();\
\
\
\
--多选对话框\
items={}\
for i=1,5 do\
table.insert(items,\"多选项目\"..tostring(i))\
end\
多选对话框=AlertDialog.Builder(this)\
.setTitle(\"多选框\")\
.setMultiChoiceItems(items, nil,{ onClick=function(v,p)print(items[p+1])end})\
多选对话框.show();" ;
      --14
      "--ProgressDialog__进度条对话框\
\
dialog = ProgressDialog.show(this, \"提示\", \"正在登陆中\").hide()\
--最简单便捷的方式\
\
dialog2 = ProgressDialog.show(this, \"提示\", \"正在登陆中\", false).hide()\
--最后一个boolean设置是否是不明确的状态\
\
dialog3 = ProgressDialog.show(this, \"提示\", \"正在登陆中\",false, true).hide()\
--最后一个boolean设置可以不可以点击取消\
\
dialog4 = ProgressDialog.show(this, \"提示\", \"正在登陆中\",false, true, DialogInterface.OnCancelListener{\
  onCancel=function()\
    print(\"对话框取消\")\
  end\
}).hide() \
\
--最后一个参数监听对话框取消，并执行事件\
\
\
\
\
\
--圆形旋转样式\
dialog5= ProgressDialog(this)\
dialog5.setProgressStyle(ProgressDialog.STYLE_SPINNER)\
dialog5.setTitle(\"Loading...\")\
--设置进度条的形式为圆形转动的进度条\
dialog5.setMessage(\"ProgressDialog\")\
dialog5.setCancelable(true)--设置是否可以通过点击Back键取消\
dialog5.setCanceledOnTouchOutside(false)--设置在点击Dialog外是否取消Dialog进度条\
dialog5.setOnCancelListener{\
  onCancel=function(l)\
    print(\"取消Dialog5\")\
  end}\
--取消对话框监听事件\
dialog5.show().hide()\
\
\
\
\
\
--水平样式\
dialog6= ProgressDialog(this)\
dialog6.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);\
--设置进度条的形式为水平进度条\
dialog6.setTitle(\"ProgressDialog_HORIZONTAL\")\
dialog6.setCancelable(true)--设置是否可以通过点击Back键取消\
dialog6.setCanceledOnTouchOutside(false)--设置在点击Dialog外是否取消Dialog进度条\
dialog6.setOnCancelListener{\
  onCancel=function(l)\
    print(\"取消Dialog6\")\
  end}\
--取消对话框监听事件\
dialog6.setMax(100)\
--设置最大进度值\
dialog6.show().hide()\
\
function 增加(i)\
  dialog6.incrementProgressBy(10)\
  dialog6.incrementSecondaryProgressBy(10)\
  if i==\"10\" then\
    dialog6.dismiss()\
    print(\"加载完成\")\
  end\
  --当进度走完时销毁对话框\
end\
function 加载()\
  require \"import\"\
  for i=1,10 do\
    Thread.sleep(300)\
    call(\"增加\",tostring(i))\
  end\
end\
--thread(加载)" ;
      --15
      "在Android的开发中，有时候会遇到软键盘弹出时挡住输入框的情况。\
这时候可以设置下软键盘的模式就可以了。\
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE|WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)\
有时候需要软键盘不要把我们的布局整体推上去，这时候可以这样：\
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)\
\
模式常量：\
\
软输入区域是否可见。\
SOFT_INPUT_MASK_STATE = 0x0f\
\
未指定状态。\
SOFT_INPUT_STATE_UNSPECIFIED = 0\
\
不要修改软输入法区域的状态\
SOFT_INPUT_STATE_UNCHANGED = 1\
\
隐藏输入法区域（当用户进入窗口时\
SOFT_INPUT_STATE_HIDDEN = 2\
\
当窗口获得焦点时，隐藏输入法区域\
SOFT_INPUT_STATE_ALWAYS_HIDDEN = 3\
\
显示输入法区域（当用户进入窗口时）\
SOFT_INPUT_STATE_VISIBLE = 4\
\
当窗口获得焦点时，显示输入法区域\
SOFT_INPUT_STATE_ALWAYS_VISIBLE = 5\
\
窗口应当主动调整，以适应软输入窗口。\
SOFT_INPUT_MASK_ADJUST = 0\
\
窗口应当主动调整，以适应软输入窗口。\
SOFT_INPUT_MASK_ADJUST = 0xf0\
\
未指定状态，系统将根据窗口内容尝试选择一个输入法样式。\
SOFT_INPUT_ADJUST_UNSPECIFIED = 0x00\
\
当输入法显示时，允许窗口重新计算尺寸，使内容不被输入法所覆盖。\
不可与SOFT_INPUT_ADJUSP_PAN混合使用；如果两个都没有设置，系统将根据窗口内容自动设置一个选项。\
SOFT_INPUT_ADJUST_RESIZE = 0x10\
\
输入法显示时平移窗口。它不需要处理尺寸变化，框架能够移动窗口以确保输入焦点可见。\
不可与SOFT_INPUT_ADJUST_RESIZE混合使用；如果两个都没有设置，系统将根据窗口内容自动设置一个选项。\
SOFT_INPUT_ADJUST_PAN = 0x20\
\
当用户转至此窗口时，由系统自动设置，所以你不要设置它。\
当窗口显示之后该标志自动清除。\
SOFT_INPUT_IS_FORWARD_NAVIGATION = 0x100\
\
\
其它Api参考:\
import \"android.view.inputmethod.InputMethodManager\"\
 \
\
调用显示系统默认的输入法\
imm =  activity.getSystemService(Context.INPUT_METHOD_SERVICE)\
imm.showSoftInput(m_receiverView(接受软键盘输入的视图(View)),InputMethodManager.SHOW_FORCED(提供当前操作的标记，SHOW_FORCED表示强制显示))\
\
\
\
如果输入法关闭则打开，如果输入法打开则关闭\
imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE)\
imm.toggleSoftInput(0,InputMethodManager.HIDE_NOT_ALWAYS)\
  \
\
获取软键盘是否打开\
imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE)\
isOpen=imm.isActive()\
--返回一个布尔值\
\
\
隐藏软键盘\
activity.getSystemService(INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(WidgetSearchActivity.this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS)\
\
显示软键盘\
activity.getSystemService(INPUT_METHOD_SERVICE)).showSoftInput(控件ID, 0)" ;
      --16
      "pop=PopupMenu(activity,view)\
menu=pop.Menu\
menu.add(\"项目1\").onMenuItemClick=function(a)\
\
end\
menu.add(\"项目2\").onMenuItemClick=function(a)\
\
end\
pop.show()--显示" ;
      --17
      "pop=PopWindow(activity)--创建PopWindow\
pop.setContentView(loadlayout(布局))--设置布局\
pop.setWidth(activity.Width*0.3)--设置宽度\
pop.setHeight(activity.Width*0.3)--设置高度\
pop.setFocusable(true)--设置可获得焦点\
window.setTouchable(true)--设置可触摸\
--设置点击外部区域是否可以消失\
pop.setOutsideTouchable(false)\
--显示\
pop.showAtLocation(view,0,0,0)" ;
      --18
      "--默认Toast\
Toast.makeText(activity, \"Toast\",Toast.LENGTH_SHORT).show()\
\
--自定义位置Toast\
Toast.makeText(activity,\"自定义位置Toast\", Toast.LENGTH_LONG).setGravity(Gravity.CENTER, 0, 0).show()\
\
--带图片Toast\
图片=loadbitmap(\"/sdcard/a.png\")\
toast = Toast.makeText(activity,\"带图片的Toast\", Toast.LENGTH_LONG)\
toastView = toast.getView()\
imageCodeProject = ImageView(activity)\
imageCodeProject.setImageBitmap(图片)\
toastView.addView(imageCodeProject, 0)\
toast.show()\
\
--自定义布局Toast\
布局=loadlayout(layout)\
local toast=Toast.makeText(activity,\"提示\",Toast.LENGTH_SHORT).setView(布局).show()" ;
      --19
      "--EditText(输入框)\
singleLine=true--设置单行输入\
Error=\"错误的输入\"--设置用户输入了错误的信息时的提醒\
MaxLines=5--设置最大输入行数\
MaxEms=5--设置每行最大宽度为五个字符的宽度\
InputType=\"number\"--设置只可输入数字\
Hint=\"请输入\"--设置编辑框为空时的提示文字\
\
\
--ImageView(图片视图)\
src=\"a.png\"--设置控件图片资源\
scaleType=\"fitXY\"--设置图片缩放显示\
ColorFilter=Color.BLUE--设置图片着色\
\
\
\
--ListView(列表视图)\
Items={\"item1\",\"item2\",\"item3\"}--设置列表项目,但只能在布局表设置,动态添加项目请看Adapter View详解。\
DividerHeight=0--设置无隔断线\
fastScrollEnabled=true--设置是否显示快速滑块\
\
\
\
layout_marginBottom--离某元素底边缘的距离\
layout_marginLeft--离某元素左边缘的距离\
layout_marginRight--离某元素右边缘的距离\
layout_marginTop--离某元素上边缘的距离\
gravity--属性是对该view 内容的限定．比如一个button 上面的text. 你可以设置该text 在view的靠左，靠右等位置．以button为例，gravity=\"right\"则button上面的文字靠右\
layout_gravity--是用来设置该view相对与起父view 的位置．比如一个button 在linearlayout里，你想把该button放在靠左、靠右等位置就可以通过该属性设置．以button为例，layout_gravity=\"right\"则button靠右\
scaleType\
--[[是控制图片如何resized/moved来匹对ImageView的size。ImageView.ScaleType / scaleType值的意义区别：\
CENTER /center 按图片的原来size居中显示，当图片长/宽超过View的长/宽，则截取图片的居中部分显示\
CENTER_CROP / centerCrop 按比例扩大图片的size居中显示，使得图片长(宽)等于或大于View的长(宽)\
CENTER_INSIDE / centerInside 将图片的内容完整居中显示，通过按比例缩小或原来的size使得图片长/宽等于或小于View的长/宽\
FIT_CENTER / fitCenter 把图片按比例扩大/缩小到View的宽度，居中显示\
FIT_END / fitEnd 把图片按比例扩大/缩小到View的宽度，显示在View的下部分位置\
FIT_START / fitStart 把图片按比例扩大/缩小到View的宽度，显示在View的上部分位置\
FIT_XY / fitXY 把图片不按比例扩大/缩小到View的大小显示\
MATRIX / matrix 用矩阵来绘制，动态缩小放大图片来显示。\
]]\
id--为控件指定相应的ID\
text--指定控件当中显示的文字\
textSize--指定控件当中字体的大小\
background--指定该控件所使用的背景色\
width--指定控件的宽度\
height--指定控件的高度\
layout_width--指定Container组件的宽度\
layout_height--指定Container组件的高度\
layout_weight--View中很重要的属性，按比例划分空间\
padding--指定控件的内边距，也就是说控件当中的内容\
sigleLine--如果设置为真的话，则控件的内容在同一行中进行显示" ;
      --20
      "--动画主要包括以下几种\
Alpha:渐变透明度动画效果\
Scale:渐变尺寸伸缩动画效果\
Translate:画面转换位置移动动画效果\
Rotate:画面转换位置移动动画效果\
\
--共有的属性有\
Duration --属性为动画持续时间 时间以毫秒为单位\
fillAfter --当设置为true,该动画转化在动画结束后被应用\
fillBefore --当设置为true,该动画转化在动画开始前被应用\
repeatCount--动画的重复次数 \
repeatMode --定义重复的行为 \
startOffset --动画之间的时间间隔，从上次动画停多少时间开始执行下个动画\
id.startAnimation(Animation)--设置控件开始应用这个动画\
\
\
\
--动画状态监听\
import \"android.view.animation.Animation$AnimationListener\"\
动画.setAnimationListener(AnimationListener{\
  onAnimationStart=function()\
    print\"动画开始\"\
  end,\
onAnimationEnd=function()\
  print\"动画结束\"\
  end,\
onAnimationRepeat=function()\
  print\"动画重复\"\
  end})\
\
\
--实例\
--控件向右旋转180度\
Rotate_right=RotateAnimation(180, 0,\
Animation.RELATIVE_TO_SELF, 0.5, \
Animation.RELATIVE_TO_SELF, 0.5)\
Rotate_right.setDuration(440)\
Rotate_right.setFillAfter(true)\
\
--控件向左旋转180度\
Rotate_left=RotateAnimation(0, 180,\
Animation.RELATIVE_TO_SELF, 0.5, \
Animation.RELATIVE_TO_SELF, 0.5)\
Rotate_left.setDuration(440)\
Rotate_left.setFillAfter(true)\
\
\
\
--动画设置___从上往下平移动画\
Translate_up_down=TranslateAnimation(0, 0, 55, 0)\
Translate_up_down.setDuration(800)\
Translate_up_down.setFillAfter(true)\
\
\
\
--动画设置___透明动画\
Alpha=AlphaAnimation(0,1)\
Alpha.setDuration(800)\
\
\
--动画参数值\
--AlphaAnimation(透明动画)\
AlphaAnimation(float fromStart,float fromEnd)\
float fromStart 动画起始透明值\
float fromEnd 动画结束透明值\
\
--ScaleAnimation(缩放动画)\
ScaleAnimation(float fromX, float toX, float fromY, float toY,int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) \
float fromX 动画起始时 X坐标上的伸缩尺寸 \
float toX 动画结束时 X坐标上的伸缩尺寸 \
float fromY 动画起始时Y坐标上的伸缩尺寸 \
float toY 动画结束时Y坐标上的伸缩尺寸 \
int pivotXType 动画在X轴相对于物件位置类型 \
float pivotXValue 动画相对于物件的X坐标的开始位置 \
int pivotYType 动画在Y轴相对于物件位置类型 \
float pivotYValue 动画相对于物件的Y坐标的开始位置 \
\
\
--TranslateAnimation(位移动画)\
TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)\
float fromXDelta 动画开始的点离当前View X坐标上的差值 \
float toXDelta 动画结束的点离当前View X坐标上的差值 \
float fromYDelta 动画开始的点离当前View Y坐标上的差值 \
float toYDelta 动画结束的点离当前View Y坐标上的差值 \
\
--RotateAnimation(旋转动画)\
RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) \
float fromDegrees：旋转的开始角度.\
float toDegrees：旋转的结束角度.\
int pivotXType：X轴的伸缩模式，可以取值为ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT.\
float pivotXValue：X坐标的伸缩值\
int pivotYType：Y轴的伸缩模式，可以取值为ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT.\
float pivotYValue：Y坐标的伸缩值." ;
      --21
      "--LayoutAnimationController可以控制一组控件按照规定显示 \
\
--导入类\
import \"android.view.animation.AnimationUtils\"\
import \"android.view.animation.LayoutAnimationController\"\
\
\
--创建一个Animation对象\
animation = AnimationUtils.loadAnimation(activity,android.R.anim.slide_in_left)\
\
--得到对象\
lac = LayoutAnimationController(animation)\
\
--设置控件显示的顺序\
lac.setOrder(LayoutAnimationController.ORDER_NORMAL)\
--LayoutAnimationController.ORDER_NORMAL   顺序显示\
--LayoutAnimationController.ORDER_REVERSE 反显示\
--LayoutAnimationController.ORDER_RANDOM 随机显示\
\
--设置控件显示间隔时间\
lac.setDelay(time)\
\
--设置组件应用\
view.setLayoutAnimation(lac)" ;
      --22
      "ObjectAnimator(对象动画)\
--属性动画概念：\
所谓属性动画：\
改变一切能改变的对象的属性值，不同于补间动画\
只能改变 alpha，scale，rotate，translate\
听着有点抽象，举例子说明。\
\
\
补间动画能实现的:\
1.alpha(透明)\
--第一个参数为 view对象,第二个参数为 动画改变的类型,第三,第四个参数依次是开始透明度和结束透明度。\
alpha = ObjectAnimator.ofFloat(text, \"alpha\", 0, 1)\
alpha.setDuration(2000)--设置动画时间\
alpha.setInterpolator(DecelerateInterpolator())--设置动画插入器，减速\
alpha.setRepeatCount(-1)--设置动画重复次数，这里-1代表无限\
alpha.setRepeatMode(Animation.REVERSE)--设置动画循环模式。\
alpha.start()--启动动画。\
\
2.scale(缩放)\
animatorSet =  AnimatorSet()--组合动画\
scaleX = ObjectAnimator.ofFloat(text, \"scaleX\", 1, 0)\
scaleY = ObjectAnimator.ofFloat(text, \"scaleY\", 1, 0)\
animatorSet.setDuration(2000)\
animatorSet.setInterpolator(DecelerateInterpolator());\
animatorSet.play(scaleX).with(scaleY)--两个动画同时开始\
animatorSet.start();\
\
3.translate(平移)\
translationUp = ObjectAnimator.ofFloat(button, \"Y\",button.getY(), 0)\
translationUp.setInterpolator(DecelerateInterpolator())\
translationUp.setDuration(1500)\
translationUp.start()\
\
4. rotate(旋转)\
set =  AnimatorSet()\
anim = ObjectAnimator .ofFloat(phone, \"rotationX\", 0, 180)\
anim.setDuration(2000)\
anim2 = ObjectAnimator .ofFloat(phone, \"rotationX\", 180, 0)\
anim2.setDuration(2000)\
anim3 = ObjectAnimator .ofFloat(phone, \"rotationY\", 0, 180)\
anim3.setDuration(2000)\
anim4 = ObjectAnimator .ofFloat(phone, \"rotationY\", 180, 0)\
anim4.setDuration(2000)\
set.play(anim).before(anim2)--先执行anim动画之后在执行anim2\
set.play(anim3).before(anim4)\
set.start()\
\
\
补间动画不能实现的:\
5.android 改变背景颜色的动画实现如下\
translationUp = ObjectAnimator.ofInt(button,\"backgroundColor\",{Color.RED, Color.BLUE, Color.GRAY,Color.GREEN})\
translationUp.setInterpolator(DecelerateInterpolator())\
translationUp.setDuration(1500)\
translationUp.setRepeatCount(-1)\
translationUp.setRepeatMode(Animation.REVERSE)\
translationUp.setEvaluator(ArgbEvaluator())\
translationUp.start()\
--[[\
ArgbEvaluator：这种评估者可以用来执行类型之间的插值整数值代表ARGB颜色。\
FloatEvaluator：这种评估者可以用来执行浮点值之间的插值。\
IntEvaluator：这种评估者可以用来执行类型int值之间的插值。\
RectEvaluator：这种评估者可以用来执行类型之间的插值矩形值。\
\
由于本例是改变View的backgroundColor属性的背景颜色所以此处使用ArgbEvaluator\
]]" ;
      --23
      "activity.overridePendingTransition(android.R.anim.fade_in,android.R.anim.fade_out)" ;
      --24
      "--靛蓝配粉色\
靛蓝色=0xFF3F51B5\
粉色=0xFFE91E63\
\
--蓝色配青绿色\
蓝色=0xFF2196F3\
青绿色=0xFF009688\
\
--其它:\
暗橙色=0xFFFF5722\
酸橙色=0xFFCDDC39\
深紫色=0xFF673AB7\
青色=0xFF0097A7\
红色=0xFFF44336\
亮蓝=0xFF03A9F4" ;
    },
    实用代码={
      --1
      "import \"android.provider.Settings$Secure\"\
android_id = Secure.getString(activity.getContentResolver(), Secure.ANDROID_ID)" ;
      --2
      "import \"android.content.Context\" \
imei=activity.getSystemService(Context.TELEPHONY_SERVICE).getDeviceId()" ;
      --3
      "view=控件id\
color1 = 0xffFF8080;\
color2 = 0xff8080FF;\
color3 = 0xff80ffff;\
color4 = 0xff80ff80;\
import \"android.animation.ObjectAnimator\"\
import \"android.animation.ArgbEvaluator\"\
import \"android.animation.ValueAnimator\"\
import \"android.graphics.Color\"\
colorAnim = ObjectAnimator.ofInt(view,\"backgroundColor\",{color1, color2, color3,color4})\
colorAnim.setDuration(3000)\
colorAnim.setEvaluator(ArgbEvaluator())\
colorAnim.setRepeatCount(ValueAnimator.INFINITE)\
colorAnim.setRepeatMode(ValueAnimator.REVERSE)\
colorAnim.start()" ;
      --4
      "function getScreenPhysicalSize(ctx) \
  import \"android.util.DisplayMetrics\"\
  dm = DisplayMetrics();\
  ctx.getWindowManager().getDefaultDisplay().getMetrics(dm);\
  diagonalPixels = Math.sqrt(Math.pow(dm.widthPixels, 2) + Math.pow(dm.heightPixels, 2));\
  return diagonalPixels / (160 * dm.density);\
end\
print(getScreenPhysicalSize(activity))" ;
      --5
      "import \"android.content.Intent\"\
i = Intent(Intent.ACTION_SEND)\
i.setType(\"message/rfc822\") \
i.putExtra(Intent.EXTRA_EMAIL, {\"2113075983@.com\"})\
i.putExtra(Intent.EXTRA_SUBJECT,\"Feedback\")\
i.putExtra(Intent.EXTRA_TEXT,\"Content\")\
activity.startActivity(Intent.createChooser(i, \"Choice\"))" ;
      --6
      "dialog=AlertDialog.Builder(this)\
.setTitle(\"标题\")\
.setMessage(\"消息\")\
.setPositiveButton(\"积极\",{onClick=function(v) print\"点击了积极按钮\"end})\
.setNeutralButton(\"中立\",nil)\
.setNegativeButton(\"否认\",nil)\
.show()\
dialog.create()\
\
\
--更改消息颜色\
message=dialog.findViewById(android.R.id.message)\
message.setTextColor(0xff1DA6DD)\
\
--更改Button颜色\
import \"android.graphics.Color\"\
dialog.getButton(dialog.BUTTON_POSITIVE).setTextColor(0xff1DA6DD)\
dialog.getButton(dialog.BUTTON_NEGATIVE).setTextColor(0xff1DA6DD)\
dialog.getButton(dialog.BUTTON_NEUTRAL).setTextColor(0xff1DA6DD)\
\
--更改Title颜色\
import \"android.text.SpannableString\"\
import \"android.text.style.ForegroundColorSpan\"\
import \"android.text.Spannable\"\
sp = SpannableString(\"标题\")\
sp.setSpan(ForegroundColorSpan(0xff1DA6DD),0,#sp,Spannable.SPAN_EXCLUSIVE_INCLUSIVE)\
dialog.setTitle(sp)" ;
      --7
      "--获取手机内置剩余存储空间\
 function GetSurplusSpace()\
 fs =  StatFs(Environment.getDataDirectory().getPath())\
 return Formatter.formatFileSize(activity, (fs.getAvailableBytes()))\
 end\
\
 --获取手机内置存储总空间\
 function GetTotalSpace()\
 path = Environment.getExternalStorageDirectory()\
 stat = StatFs(path.getPath())\
 blockSize = stat.getBlockSize()\
 totalBlocks = stat.getBlockCount()\
 return Formatter.formatFileSize(activity, blockSize * totalBlocks)\
 end" ;
      --8
      "function GetVideoFrame(path)\
  import \"android.media.MediaMetadataRetriever\"\
  media = MediaMetadataRetriever()\
  media.setDataSource(tostring(path))\
  return media.getFrameAtTime()\
end" ;
      --9
      "import \"android.widget.ArrayAdapter\"\
import \"android.widget.LinearLayout\"\
import \"android.widget.TextView\"\
import \"java.io.File\"\
import \"android.widget.ListView\"\
import \"android.app.AlertDialog\"\
function ChoiceFile(StartPath,callback)\
  --创建ListView作为文件列表\
  lv=ListView(activity).setFastScrollEnabled(true)\
  --创建路径标签\
  cp=TextView(activity)\
  lay=LinearLayout(activity).setOrientation(1).addView(cp).addView(lv)\
  ChoiceFile_dialog=AlertDialog.Builder(activity)--创建对话框\
  .setTitle(\"选择文件\")\
  .setView(lay)\
  .show()\
  adp=ArrayAdapter(activity,android.R.layout.simple_list_item_1)\
  lv.setAdapter(adp)\
  function SetItem(path)\
    path=tostring(path)\
    adp.clear()--清空适配器\
    cp.Text=tostring(path)--设置当前路径\
    if path~=\"/\" then--不是根目录则加上../\
      adp.add(\"../\")\
    end\
    ls=File(path).listFiles()\
    if ls~=nil then\
      ls=luajava.astable(File(path).listFiles()) --全局文件列表变量\
      table.sort(ls,function(a,b)\
        return (a.isDirectory()~=b.isDirectory() and a.isDirectory()) or ((a.isDirectory()==b.isDirectory()) and a.Name<b.Name)\
      end)\
    else\
      ls={}\
    end\
    for index,c in ipairs(ls) do\
      if c.isDirectory() then--如果是文件夹则\
        adp.add(c.Name..\"/\")\
      else--如果是文件则\
        adp.add(c.Name)\
      end\
    end\
  end\
  lv.onItemClick=function(l,v,p,s)--列表点击事件\
    项目=tostring(v.Text)\
    if tostring(cp.Text)==\"/\" then\
      路径=ls[p+1]\
    else\
      路径=ls[p]\
    end\
\
    if 项目==\"../\" then\
      SetItem(File(cp.Text).getParentFile())\
    elseif 路径.isDirectory() then\
      SetItem(路径)\
    elseif 路径.isFile() then\
      callback(tostring(路径))\
      ChoiceFile_dialog.hide()\
    end\
\
  end\
\
  SetItem(StartPath)\
end\
\
--ChoiceFile(StartPath,callback)\
--第一个参数为初始化路径,第二个为回调函数\
--原创" ;
      --10
      "require \"import\"\
import \"android.widget.ArrayAdapter\"\
import \"android.widget.LinearLayout\"\
import \"android.widget.TextView\"\
import \"java.io.File\"\
import \"android.widget.ListView\"\
import \"android.app.AlertDialog\"\
function ChoicePath(StartPath,callback)\
  --创建ListView作为文件列表\
  lv=ListView(activity).setFastScrollEnabled(true)\
  --创建路径标签\
  cp=TextView(activity)\
  lay=LinearLayout(activity).setOrientation(1).addView(cp).addView(lv)\
  ChoiceFile_dialog=AlertDialog.Builder(activity)--创建对话框\
  .setTitle(\"选择路径\")\
  .setPositiveButton(\"OK\",{\
  onClick=function()\
  callback(tostring(cp.Text))\
  end})\
.setNegativeButton(\"Canel\",nil)\
  .setView(lay)\
  .show()\
  adp=ArrayAdapter(activity,android.R.layout.simple_list_item_1)\
  lv.setAdapter(adp)\
  function SetItem(path)\
    path=tostring(path)\
    adp.clear()--清空适配器\
    cp.Text=tostring(path)--设置当前路径\
    if path~=\"/\" then--不是根目录则加上../\
      adp.add(\"../\")\
    end\
    ls=File(path).listFiles()\
    if ls~=nil then\
      ls=luajava.astable(File(path).listFiles()) --全局文件列表变量\
      table.sort(ls,function(a,b)\
        return (a.isDirectory()~=b.isDirectory() and a.isDirectory()) or ((a.isDirectory()==b.isDirectory()) and a.Name<b.Name)\
      end)\
    else\
      ls={}\
    end\
    for index,c in ipairs(ls) do\
      if c.isDirectory() then--如果是文件夹则\
        adp.add(c.Name..\"/\")\
      end\
    end\
  end\
  lv.onItemClick=function(l,v,p,s)--列表点击事件\
    项目=tostring(v.Text)\
    if tostring(cp.Text)==\"/\" then\
      路径=ls[p+1]\
    else\
      路径=ls[p]\
    end\
\
    if 项目==\"../\" then\
      SetItem(File(cp.Text).getParentFile())\
    elseif 路径.isDirectory() then\
      SetItem(路径)\
    elseif 路径.isFile() then\
      callback(tostring(路径))\
      ChoiceFile_dialog.hide()\
    end\
\
  end\
\
  SetItem(StartPath)\
end\
\
\
import \"android.os.*\"\
ChoicePath(Environment.getExternalStorageDirectory().toString(),\
function(path)\
print(path)\
end)\
\
--第一个参数为初始化路径,第二个为回调函数\
--原创" ;
      --11
      "function GetAllText(view)\
textTable={}\
function GetText(Parent)\
local number=Parent.getChildCount()\
for i=0,number do\
local view=Parent.getChildAt(i)\
if pcall(function()view.addView(TextView(activity))end) then\
GetText(view)\
elseif pcall(function()view.getText()end) then\
table.insert(textTable,tostring(view.Text))\
end\
end\
end\
GetText(view)\
return textTable\
end\
\
print(table.unpack(GetAllText(Parent)))" ;
      --12
      "function CircleButton(view,InsideColor,radiu)\
  import \"android.graphics.drawable.GradientDrawable\"\
  drawable = GradientDrawable() \
  drawable.setShape(GradientDrawable.RECTANGLE) \
  drawable.setColor(InsideColor)\
  drawable.setCornerRadii({radiu,radiu,radiu,radiu,radiu,radiu,radiu,radiu});\
  view.setBackgroundDrawable(drawable)\
end\
角度=50\
控件id=ed\
控件颜色=0xFF09639C\
CircleButton(控件id,控件颜色,角度)" ;
      --13
      "function filter_spec_chars(s)\
\9local ss = {}\
\9for k = 1, #s do\
\9\9local c = string.byte(s,k)\
\9\9if not c then break end\
\9\9if (c>=48 and c<=57) or (c>= 65 and c<=90) or (c>=97 and c<=122) then\
\9\9\9if not string.char(c):find(\"%w\") then\
   table.insert(ss, string.char(c))\
\9end\
 \9elseif c>=228 and c<=233 then\
\9\9\9local c1 = string.byte(s,k+1)\
\9\9\9local c2 = string.byte(s,k+2)\
\9\9\9if c1 and c2 then\
\9\9\9\9local a1,a2,a3,a4 = 128,191,128,191\
\9\9\9\9if c == 228 then a1 = 184\
\9\9\9\9elseif c == 233 then a2,a4 = 190,c1 ~= 190 and 191 or 165\
\9\9\9\9end\
\9\9\9\9if c1>=a1 and c1<=a2 and c2>=a3 and c2<=a4 then\
\9\9\9\9\9k = k + 2\
\9\9\9\9\9table.insert(ss, string.char(c,c1,c2))\
\9\9\9\9end\
\9\9\9end\
\9\9end\
\9end\
\9return table.concat(ss)\
end\
print(filter_spec_chars(\"A1B2汉C3D4字E5F6,,,\"))\
--来源网络,加了个if过滤掉英文与数字,使其只捕获中文" ;
      --14
      "import \"android.media.MediaPlayer\"\
mediaPlayer =  MediaPlayer()\
\13\
--初始化参数\13\
mediaPlayer.reset()\
\13\
--设置播放资源\13\
mediaPlayer.setDataSource(\"storage/sdcard0/a.mp3\")\
\13\
--开始缓冲资源\13\
mediaPlayer.prepare()\
\13\
--是否循环播放该资源\13\
mediaPlayer.setLooping(true)\
\13\
--缓冲完成的监听\13\
mediaPlayer.setOnPreparedListener(MediaPlayer.OnPreparedListener() {\13\
    onPrepared=function(mediaPlayer\
        mediaPlayer.start()\
   end});\13\
\13\
--是否在播放\13\
mediaPlayer.isPlaying()\
\13\
--暂停播放\
mediaPlayer.pause()\
\13\
--从30位置开始播放\13\
mediaPlayer.seekTo(30)\
\13\
--停止播放\13\
mediaPlayer.stop()\
\13\
\
\
\
\
\
--播放视频\
--视频的播放与音乐播放过程一样：\13\
\13\
--先创建一个媒体对象\13\
import \"android.media.MediaPlayer\"\
mediaPlayer =  MediaPlayer()\
--初始化参数\13\
mediaPlayer.reset()\
\
--设置播放资源\13\
mediaPlayer.setDataSource(\"storage/sdcard0/a.mp4\")\
\13\
--拿到显示的SurfaceView\13\
sh = surfaceView.getHolder()\
sh.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS)\
\13\
--设置显示SurfaceView\13\
mediaPlayer.setDisplay(sh)\
\13\
--设置音频流格式\13\
mediaPlayer.setAudioStreamType(AudioManager.Stream_Music)\
\13\
--开始缓冲资源\13\
mediaPlayer.prepare()\
\13\
--缓冲完成的监听\13\
mediaPlayer.setOnPreparedListener(MediaPlayer.OnPreparedListener{\13\
   onPrepared=function(mediaPlayer)\
\9\9--开始播放\13\
        mediaPlayer.start()\
   end\
});\13\
\13\
--释放播放器\13\
mediaPlayer.release()\
\
\
--非原创" ;
      --15
      "device_model = Build.MODEL --设备型号 \
\
version_sdk = Build.VERSION.SDK --设备SDK版本 \
\
version_release = Build.VERSION.RELEASE --设备的系统版本" ;
      --16
      "import \"android.graphics.PorterDuffColorFilter\"\
import \"android.graphics.PorterDuff\"\
\
--修改按钮颜色\
button.getBackground().setColorFilter(PorterDuffColorFilter(0xFFFB7299,PorterDuff.Mode.SRC_ATOP))\
\
--修改编辑框颜色\
edittext.getBackground().setColorFilter(PorterDuffColorFilter(0xFFFB7299,PorterDuff.Mode.SRC_ATOP));\
\
--修改Switch颜色\
switch.ThumbDrawable.setColorFilter(PorterDuffColorFilter(0xFFFB7299,PorterDuff.Mode.SRC_ATOP));\
switch.TrackDrawable.setColorFilter(PorterDuffColorFilter(0xFFFB7299,PorterDuff.Mode.SRC_ATOP))\
\
--修改ProgressBar颜色\
progressbar.IndeterminateDrawable.setColorFilter(PorterDuffColorFilter(0xFFFB7299,PorterDuff.Mode.SRC_ATOP))\
\
--修改SeekBar滑条颜色\
seekbar.ProgressDrawable.setColorFilter(PorterDuffColorFilter(0xFFFB7299,PorterDuff.Mode.SRC_ATOP))\
--修改SeekBar滑块颜色\
seekbar.Thumb.setColorFilter(PorterDuffColorFilter(0xFFFB7299,PorterDuff.Mode.SRC_ATOP))" ;
      --17
      "function DialogButtonFilter(dialog,button,WidgetColor)\
if Build.VERSION.SDK_INT >= 21 then\
import \"android.graphics.PorterDuffColorFilter\"\
import \"android.graphics.PorterDuff\"\
if button==1 then\
dialog.getButton(dialog.BUTTON_POSITIVE).setTextColor(WidgetColor)\
elseif button==2 then\
dialog.getButton(dialog.BUTTON_NEGATIVE).setTextColor(WidgetColor)\
elseif button==3 then\
dialog.getButton(dialog.BUTTON_NEUTRAL).setTextColor(WidgetColor)\
end\
end\
end\
--第一个参数为对话框的变量\
--第二个参数为1时，则修改POSITIVE按钮颜色,为二则修改NEGATIVE按钮颜色,为三则修改NEUTRAL按钮颜色\
--第三个参数为要修改成的颜色" ;
      --18
      "function QueryAllVideo()\
import \"android.provider.MediaStore\"\
cursor = activity.ContentResolver\
mImageUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;\
mCursor = cursor.query(mImageUri,nil,nil,nil,MediaStore.Video.Media.DATE_TAKEN)\
mCursor.moveToLast()\
VideoTable={}\
while mCursor.moveToPrevious() do\
   path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Video.Media.DATA))\
   table.insert(VideoTable,tostring(path))\
end\
mCursor.close()\
return VideoTable\
end\
--返回一个表" ;
      --19
      "function QueryAllImage()\
import \"android.provider.MediaStore\"\
cursor = activity.ContentResolver\
mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;\
mCursor = cursor.query(mImageUri,nil,nil,nil,MediaStore.Images.Media.DATE_TAKEN)\
mCursor.moveToLast()\
imageTable={}\
while mCursor.moveToPrevious() do\
   path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Images.Media.DATA))\
   table.insert(imageTable,tostring(path))\
end\
mCursor.close()\
return imageTable\
end\
--返回一个表" ;
      --20
      "function outPath(ret) \
for i,p in pairs(luajava.astable(ret)) do\
print(p)\
end\
end\
function find(catalog,name)\
 local n=0\
 local t=os.clock()\
 local ret={}\
 require \"import\"\
 import \"java.io.File\" \
 import \"java.lang.String\"\
 function FindFile(catalog,name)\
   local name=tostring(name)\
   local ls=catalog.listFiles() or File{}\
   for 次数=0,#ls-1 do\
     --local 目录=tostring(ls[次数])\
     local f=ls[次数]\
     if f.isDirectory() then--如果是文件夹则继续匹配\
       FindFile(f,name)\
     else--如果是文件则\
       n=n+1\
       if n%1000==0 then\
         print(n,os.clock()-t)\
       end\
      local nm=f.Name\
       if string.find(nm,name) then\
         --thread(insert,目录)\
         table.insert(ret,tostring(f))\
       end\
     end\
   luajava.clear(f)\
   end\
 end\
 FindFile(catalog,name)\
 call(\"outPath\",ret)\
end\
\
import \"java.io.File\"\
\
catalog=File(\"/sdcard/AndroLua\")\
name=\".j?pn?g\"\
thread(find,catalog,name)" ;
      --21
      "Environment.getExternalStorageDirectory().toString()" ;
      --22
      "function GetAppInfo(包名)\
  import \"android.content.pm.PackageManager\"\
  local pm = activity.getPackageManager();\
  local 图标 = pm.getApplicationInfo(tostring(包名),0)\
  local 图标 = 图标.loadIcon(pm);\
  local pkg = activity.getPackageManager().getPackageInfo(包名, 0); \
  local 应用名称 = pkg.applicationInfo.loadLabel(activity.getPackageManager())\
  local 版本号 = activity.getPackageManager().getPackageInfo(包名, 0).versionName\
  local 最后更新时间 = activity.getPackageManager().getPackageInfo(包名, 0).lastUpdateTime\
  local cal = Calendar.getInstance();\
  cal.setTimeInMillis(最后更新时间); \
  local 最后更新时间 = cal.getTime().toLocaleString()\
  return 包名,版本号,最后更新时间,图标,应用名称\
end" ;
      --23
      "import \"android.content.pm.PackageManager\"\
import \"android.content.pm.ApplicationInfo\"\
function GetApkInfo(archiveFilePath)\
pm = activity.getPackageManager()\
info = pm.getPackageArchiveInfo(archiveFilePath, PackageManager.GET_ACTIVITIES); \
if info ~= nil then\
  appInfo = info.applicationInfo;\
 appName = tostring(pm.getApplicationLabel(appInfo))\
  packageName = appInfo.packageName; --安装包名称 \
  version=info.versionName; --版本信息 \
   icon = pm.getApplicationIcon(appInfo);--图标\
end\
return packageName,version,icon\
end" ;
      --24
      "if pcall(function() activity.getPackageManager().getPackageInfo(\"包名\",0) end) then\
  print(\"安装了\")\
else\
  print(\"没安装\")\
end" ;
      --25
      "import \"android.graphics.Paint\"\
--设置中划线\
id.getPaint().setFlags(Paint. STRIKE_THRU_TEXT_FLAG)\
--设置下划线\
id.getPaint().setFlags(Paint. UNDERLINE_TEXT_FLAG )\
--设置加粗\
id.getPaint().setFakeBoldText(true)\
--设置斜体\
id.getPaint().setTextSkewX(0.2)\
\
--设置TypeFace\
import \"android.graphics.Typeface\"\
id.getPaint().setTypeface()\
--参数列表\
Typeface.DEFAULT 默认字体\
Typeface.DEFAULT_BOLD 加粗字体\
Typeface.MONOSPACE monospace字体\
Typeface.SANS_SERIF sans字体\
Typeface.SERIF serif字体" ;
      --26
      "function rotateToFit(bm,degrees)\
    import \"android.graphics.Matrix\"\
    import \"android.graphics.Bitmap\"\
    width = bm.getWidth()\
    height = bm.getHeight()\
    matrix =  Matrix()\
    matrix.postRotate(degrees)\
    bmResult = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true)\
    return bmResult\
  end\
bm=loadbitmap(图片路径)\
缩放级别=2\
rotateToFit(bm,degrees)\
--非原创" ;
      --27
      "import \"android.content.Context\" \
运营商名称 = this.getSystemService(Context.TELEPHONY_SERVICE).getNetworkOperatorName()\
print(运营商名称)\
--添加权限   READ_PHONE_STATE" ;
      --28
      "function ToColor(path,color)\
 local  aa=BitmapDrawable(loadbitmap(tostring(path)))\
   aa.setColorFilter(PorterDuffColorFilter(color,PorterDuff.Mode.SRC_ATOP))\
return aa\
end" ;
      --29
      "function SavePicture(name,bm)\
if  bm then\
import \"java.io.FileOutputStream\"\
import \"java.io.File\"\
import \"android.graphics.Bitmap\"\
name=tostring(name)\
f = File(name)\
out = FileOutputStream(f)\
bm.compress(Bitmap.CompressFormat.PNG,90, out)\
out.flush()\
out.close()\
return true\
else\
return false\
end\
end" ;
      --30
      "import \"android.content.Intent\"\
import \"android.net.Uri\"\
intent = Intent(\"android.intent.action.VIEW\")\
intent .setData(Uri.parse( \"market://details?id=\"..activity.getPackageName()))\
this.startActivity(intent)" ;
      --31
      "--分享文件\
function Sharing(path)\
  import \"android.webkit.MimeTypeMap\"\
  import \"android.content.Intent\"\
  import \"android.net.Uri\"\
  import \"java.io.File\"\
  FileName=tostring(File(path).Name)\
  ExtensionName=FileName:match(\"%.(.+)\")\
  Mime=MimeTypeMap.getSingleton().getMimeTypeFromExtension(ExtensionName)\
  intent = Intent();\
  intent.setAction(Intent.ACTION_SEND);\
  intent.setType(Mime);\
  file = File(path);\
  uri = Uri.fromFile(file);\
  intent.putExtra(Intent.EXTRA_STREAM,uri);\
  intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);\
  activity.startActivity(Intent.createChooser(intent, \"分享到:\"));\
  end\
\
--分享文字\
text=\"分享的内容\" \
intent=Intent(Intent.ACTION_SEND); \
intent.setType(\"text/plain\"); \
intent.putExtra(Intent.EXTRA_SUBJECT, \"分享\"); \
intent.putExtra(Intent.EXTRA_TEXT, text); \
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); \
activity.startActivity(Intent.createChooser(intent,\"分享到:\")); " ;
      --32
      "function OpenFile(path)\
  import \"android.webkit.MimeTypeMap\"\
  import \"android.content.Intent\"\
  import \"android.net.Uri\"\
  import \"java.io.File\"\
  FileName=tostring(File(path).Name)\
  ExtensionName=FileName:match(\"%.(.+)\")\
  Mime=MimeTypeMap.getSingleton().getMimeTypeFromExtension(ExtensionName)\
  if Mime then \
    intent = Intent(); \
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); \
    intent.setAction(Intent.ACTION_VIEW); \
    intent.setDataAndType(Uri.fromFile(File(path)), Mime); \
    activity.startActivity(intent);\
  else\
    Toastc(\"找不到可以用来打开此文件的程序\")\
  end\
end" ;
      --33
      "function GetRoundedCornerBitmap(bitmap,roundPx) \
  import \"android.graphics.PorterDuffXfermode\"\
  import \"android.graphics.Paint\"\
  import \"android.graphics.RectF\"\
  import \"android.graphics.Bitmap\"\
  import \"android.graphics.PorterDuff$Mode\"\
  import \"android.graphics.Rect\"\
  import \"android.graphics.Canvas\"\
  import \"android.util.Config\"\
  width = bitmap.getWidth()\
  output = Bitmap.createBitmap(width, width,Bitmap.Config.ARGB_8888)\
  canvas = Canvas(output); \
  color = 0xff424242; \
  paint = Paint()\
  rect = Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); \
  rectF = RectF(rect); \
  paint.setAntiAlias(true);\
  canvas.drawARGB(0, 0, 0, 0); \
  paint.setColor(color); \
  canvas.drawRoundRect(rectF, roundPx, roundPx, paint); \
  paint.setXfermode(PorterDuffXfermode(Mode.SRC_IN)); \
  canvas.drawBitmap(bitmap, rect, rect, paint); \
  return output; \
end\
import \"android.graphics.drawable.BitmapDrawable\"\
圆角弧度=50\
bitmap=loadbitmap(picturePath)\
RoundPic=GetRoundedCornerBitmap(bitmap)" ;
      --34
      "import \"android.net.Uri\"\
import \"android.content.Intent\"\
--加群\
url=\"mqqapi://card/show_pslcard?src_type=internal&version=1&uin=383792635&card_type=group&source=qrcode\"\
activity.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))\
\
--QQ聊天\
url=\"mqqwpa://im/chat?chat_type=wpa&uin=2113075983\"\
activity.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))" ;
      --35
      "--后台发送短信\
 require \"import\"\
 import \"android.telephony.*\"\
 SmsManager.getDefault().sendTextMessage(tostring(号码), nil, tostring(内容), nil, nil)\
\
--调用系统发送短信\
import \"android.content.Intent\"\13\
import \"android.net.Uri\"\13\
uri = Uri.parse(\"smsto:\"..号码)\
intent = Intent(Intent.ACTION_SENDTO, uri)\13\
intent.putExtra(\"sms_body\",内容)\13\
intent.setAction(\"android.intent.action.VIEW\")\
activity.startActivity(intent)" ;
      --36
      "function Table_exists(tables,value)\
for index,content in pairs(tables) do\
if content:find(value) then\
return true\
end\
end\
end" ;
      --37
      "strings=\"左中右\"\
\
--取字符串左边\
左=strings:match(\"(.+)中\")\
\
\
--取字符串中间\
中=strings:match(\"左(.-)右\")\
\
\
--取字符串右边\
右=strings:match(\"(.+)右\")\
\
--替换\
string.gsub(原字符串,替换的字符串,替换成的字符串)\
\
--匹配子串位置\
起始位置,结束位置=string.find(字符串,子串)\
\
\
--按位置捕获字符串\
string.sub(字符串,子串起始位置,子串结束位置)" ;
      --38
      "import \"android.content.Context\" \
--导入类\
\
a=activity.getSystemService(Context.CLIPBOARD_SERVICE).getText() \
--获取剪贴板 \
\
activity.getSystemService(Context.CLIPBOARD_SERVICE).setText(edit.Text) \
--写入剪贴板" ;
      --39
      "function main(...)\
  --...是newActivity传递过来的参数。\
  print(\"入口函数\",...)\
end\
\
function onCreate()\
  print(\"窗口创建\")\
end\
\
function onStart()\
  print(\"活动开始\")\
end\
\
function onResume()\
  print(\"返回程序\")\
end\
\
function onPause()\
  print(\"活动暂停\")\
end\
\
function onStop()\
  print(\"活动停止\")\
end\
\
function onDestroy()\
  print(\"程序已退出\")\
end\
\
function onResult(name,...)\
  --name：返回的活动名称\
  --...：返回的参数\
  print(\"返回活动\",name,...)\
end\
\
function onCreateOptionsMenu(menu)\
  --menu：选项菜单。\
  menu.add(\"菜单\")\
end\
\
function onOptionsItemSelected(item)\
  --item：选中的菜单项\
  print(item.Title)\
end\
\
function onConfigurationChanged(config)\
  --config：配置信息\
  print(\"屏幕方向关闭\")\
end\
\
function onKeyDown(keycode,event)\
  --keycode：键值\
  --event：事件\
  print(\"按键按下\",keycode)\
end\
\
function onKeyUp(keycode,event)\
  --keycode：键值\
  --event：事件\
  print(\"按键抬起\",keycode)\
end\
\
function onKeyLongPress(keycode,event)\
  --keycode：键值\
  --event：事件\
  print(\"按键长按\",keycode)\
end\
\
function onTouchEvent(event)\
  --event：事件\
  print(\"触摸事件\",event)\
end\
\
function onKeyDown(c,e)\
  if c==4 then\
--返回键事件\
end\
end\
\
\
id.onClick=function()\
--控件被单击\
end\
\
id.onLongClick=function()\
--控件被长按\
end\
\
\
id.onItemClick=function(p,v,i,s)\
--列表项目被单击\
项目=v.Text\
return true\
end\
\
id.onItemLongClick=function(p,v,i,s)\
--列表项目被长按\
项目=v.Text\
return true\
end\
\
\
id.onItemLongClick=function(p,v,i,s)\
--列表项目被长按\
项目=v.Text\
return true\
end\
\
--Spinner的项目单击事件\
id.onItemSelected=function(l,v,p,i) \
项目=v.Text\
end\
\
--ExpandableListView的父项目与子项目单击事件\
id.onGroupClick=function(l,v,p,s)\
  print(v.Text..\":GroupClick\")\
end\
\
id.onChildClick=function(l,v,g,c)\
  print(v.Text..\":ChildClick\")\
end" ;
      --40
      "function exec(cmd)\
local p=io.popen(string.format('%s',cmd))\
local s=p:read(\"*a\")\
p:close()\
return s\
end\
\
print(exec(\"echo  ....\"))\
\
部分常用命令:\
--删除文件或文件夹\
rm -r /路径\
\
--复制文件或文件夹\
cp -r inpath outpath\
\
--移动文件或文件夹\
mv -r inpath outpath\
\
--挂载系统目录\
mount -o remount,rw path\
\
--修改系统文件权限\
chmod 755 /system/build.prop\
\
--重启\
reboot  \
\
--关机\
reboot -p\
\
--重启至recovery\
reboot recovery" ;
    },
    文件操作={
      --1
      "--使用File类\
import \"java.io.File\"--导入File类\
File(文件路径).createNewFile()\
\
--使用io库\
io.open(\"/sdcard/aaaa\", 'w')" ;
      --2
      "--使用File类\
import \"java.io.File\"--导入File类\
File(文件夹路径).mkdir()\
\
--创建多级文件夹\
File(文件夹路径).mkdirs()\
\
--shell\
os.execute('mkdir '..文件夹路径)" ;
      --3
      "--Shell\
os.execute(\"mv \"..oldname..\" \"..newname)\
\
--os\
os.rename (oldname, newname)\
\
--File\
import \"java.io.File\"--导入File类\
File(旧).renameTo(File(新))" ;
      --4
      "io.open(文件路径,\"a+\"):write(\"更新的内容\"):close()" ;
      --5
      "io.open(文件路径,\"w+\"):write(\"更新的内容\"):close()" ;
      --6
      "io.open(文件路径,\"w\"):write(\"内容\"):close()" ;
      --7
      "function 写入文件(路径,内容)\
  import \"java.io.File\"\
  f=File(tostring(File(tostring(路径)).getParentFile())).mkdirs()\
  io.open(tostring(路径),\"w\"):write(tostring(内容)):close()\
end" ;
      --8
      "io.open(文件路径):read(\"*a\")" ;
      --9
      "for c in io.lines(文件路径) do\
print(c)\
end" ;
      --10
      "--使用File类\
import \"java.io.File\"--导入File类\
File(文件路径).delete()\
--使用os方法\
os.remove (filename)" ;
      --11
      "LuaUtil.copyDir(from,to)" ;
      --12
      "--使用LuaUtil辅助库\
LuaUtil.rmDir(路径)\
\
--使用Shell\
os.execute(\"rm -r \"..路径)" ;
      --13
      "function 替换文件字符串(路径,要替换的字符串,替换成的字符串)\
if 路径 then\
  路径=tostring(路径)\
  内容=io.open(路径):read(\"*a\")\
  io.open(路径,\"w+\"):write(tostring(内容:gsub(要替换的字符串,替换成的字符串))):close()\
else\
return false\
end\
end" ;
      --14
      "import(\"java.io.File\")\
luajava.astable(File(文件夹路径).listFiles())" ;
      --15
      "import \"java.io.File\"--导入File类\
File(路径).getName()" ;
      --16
      "function GetFileSize(path)\
  import \"java.io.File\"\
  import \"android.text.format.Formatter\"\
  size=File(tostring(path)).length()\
  Sizes=Formatter.formatFileSize(activity, size)\
  return Sizes\
end" ;
      --17
      "function GetFilelastTime(path)\
  f = File(path); \
  cal = Calendar.getInstance();\
  time = f.lastModified()\
  cal.setTimeInMillis(time); \
  return cal.getTime().toLocaleString()\
end" ;
      --18
      "import \"java.io.File\"--导入File类\
File(路径).length()" ;
      --19
      "import \"java.io.File\"--导入File类\
File(path).getParentFile()" ;
      --20
      "function GetFileMime(name)\
import \"android.webkit.MimeTypeMap\"\
ExtensionName=tostring(name):match(\"%.(.+)\")\
Mime=MimeTypeMap.getSingleton().getMimeTypeFromExtension(ExtensionName)\
return tostring(Mime)\
end\
print(GetFileMime(\"/sdcard/a.png\"))" ;
      --21
      "import \"java.io.File\"--导入File类\
File(路径).isDirectory()\
--也可用来判断文件夹存不存在" ;
      --22
      "import \"java.io.File\"--导入File类\
File(路径).isFile()\
--也可用来判断文件存不存在" ;
      --23
      "import \"java.io.File\"--导入File类\
File(路径).exists()\
\
--使用io\
function file_exists(path)\
local f=io.open(path,'r')\
if f~=nil then io.close(f) return true else return false end\
end" ;
      --24
      "import \"java.io.File\"--导入File类\
File(路径).isHidden()" ;
    },
    基础代码={
      --1
      "print\"Hello World！\"\
print(\"Hello World\")" ;
      --2
      "单行注释  --\
多行注释  --[[]]" ;
      --3
      "a=\"String\"\
a=[[String]]\
a=[===[String]===]" ;
      --4
      "a=\"Hello World\"\
\
--lua支持多重赋值\
a,b=\"String a\",\"String b\"\
\
--交换值\
a,b=\"String a\",\"String b\"\
a,b=b,a" ;
      --5
      "Lua 存在的数据类型包括:\
1.nil\
此类型只有一个值 nil。用于表示“空”值。全局变量默认为 nil，删除一个已经赋值的全局变量只需要将其赋值为 nil（对比 JavaScript，赋值 null 并不能完全删除对象的属性，属性还存在，值为 null）\
\
2.boolean\
此类型有两个值 true 和 false。在 Lua 中，false 和 nil 都表示条件假，其他值都表示条件真（区别于 C/C++ 等语言的是，0 是真）\
\
\
3.number\
双精浮点数（IEEE 754 标准），Lua 没有整数类型\
\
4.string\
你可以保存任意的二进制数据到字符串中（包括 0）。字符串中的字符是不可以改变的（需要改变时，你只能创建一个新的字符串）。获取字符串的长度，可以使用 # 操作符（长度操作符）。例如：print(#”hello”)。字符串可以使用单引号，也可以使用双引号包裹，对于多行的字符串还可以使用 [[ 和 ]] 包裹。字符串中可以使用转义字符，例如 \\n \\r 等。使用 [[ 和 ]] 包裹的字符串中的转义字符不会被转义\
\
5.userdata\
用于保存任意的 C 数据。userdata 只能支持赋值操作和比较测试\
\
6.function\
函数是第一类值（first-class value），我们能够像使用其他变量一样的使用函数（函数能够保存在变量中，可以作为参数传递给函数）\
\
7.thread\
区别于我们常常说的系统级线程\
\
8.table\
被实现为关联数组（associative arrays），可以通过任何值来进行索引（nil 除外）。和全局变量一样，table 中未赋值的域为 nil，删除一个域只需要将其赋值为 nil（实际上，全局变量就是被放置在一个 table 中）\
\
\
\
type 函数用于返回值的类型：\
print(type(\"Hello World\")) --> string\
print(type(10.4*3))        --> number\
print(type(print))         --> function\
print(type(type(X)))       --> string" ;
      --6
      "table是lua唯一的数据结构。\
table是lua中最重要的数据类型。 \
table类似于 python 中的字典。\
table只能通过构造式来创建。其他语言提供的其他数据结构如array、list等等，lua都是通过table来实现的。\
table非常实用，可以用在不同的情景下。最常用的方式就是把table当成其他语言的数组。\
\
实例1:\
mytable = {}\
for index = 1, 100 do\
    mytable[index] = math.random(1,1000)\
end\
\
说明：\
1.数组不必事先定义大小，可动态增长。\
2.创建包含100个元素的table，每个元素随机赋1-1000之间的值。\
3.可以通过mytable[x]访问任意元素，x表示索引。\
4.索引从1开始。\
\
实例2:\
tab = { a = 10, b = 20, c = 30, d = 'www.jb51.net' }\
print(tab[\"a\"]) \
\
说明：\
1.table 中的每项要求是 key = value 的形式。\
2.key 只能是字符串， 这里的 a, b, c, d 都是字符串，但是不能加上引号。\
3.通过 key 来访问 table 的值，这时候， a 必须加上引号。\
\
实例3:\
tab = { 10, s = 'abc', 11, 12, 13 } \
print(tab[1]) = 10\
print(tab[2]) = 11\
print(tab[3]) = 12\
print(tab[4]) = 13\
说明：\
1.数标从1开始。\
2.省略key，会自动以1开始编号，并跳过设置过的key。" ;
      --7
      "--Lua 支持下列比较操作符：\
\
==: 等于\
~=: 不等于\
<: 小于\
>: 大于\
<=: 小于等于\
>=: 大于等于\
这些操作的结果不是 false就是 true。" ;
      --8
      "--给定条件进行循环\
\
--输出从1到10\
for i=1,10 do\
print(i)\
end\
\
\
--输出从10到1\
for i=10,1,-1 do\
print(i)\
end\
\
--打印数组a中所有的值\
a={\"a\",\"b\",\"c\",\"d\"}\
for index,content in pairs(a) do\
print(content)\
end" ;
      --9
      "--只要条件为真便会一直循环下去\
\
--输出1到10\
a=0\
while a~=10 do\
a=a+1\
print(a)\
end\
\
--输出10到1\
a=11\
while a~=1 do\
a=a-1\
print(a)\
end\
\
--打印数组a中的所有值\
shuzu={\"a\",\"b\",\"c\",\"d\"}\
a=0\
while a~=#shuzu do\
a=a+1\
print(shuzu[a])\
end" ;
      --10
      "--判断值是否为真\
a=true\
if a then\
print(\"真\")\
else\
print(\"假\")\
end\
\
--比较值是否相同\
a=true\
b=false\
if a==b then\
print(\"真\")\
else\
print(\"假\")\
end" ;
      --11
      "函数有两个用途\
1.完成指定功能，函数作为调用语句使用\
2.计算并返回值，函数作为赋值语句的表达式使用\
\
\
实例1:\
function 读取文件(路径)\
文件内容=io.open(路径):read(\"*a\")\
return 文件内容--return用来返回值\
end\
\
\
\
实例2:\
require \"import\"\
import \"android.widget.EditText\"\
import \"android.widget.LinearLayout\"\
function 编辑框()\
return EditText(activity)\
end\
layout={\
  LinearLayout;\
  id=\"父布局\",\
  {编辑框,\
    id=\"edit\",\
    text=\"文本\",\
   },\
};\
activity.setContentView(loadlayout(layout))\
--把这段代码放到调试里面去测试" ;
      --12
      "activity.setTitle('Title')--设置窗口标题\
activity.setContentView(loadlayout(layout))--设置窗口视图\
activity.setTheme(android.R.style.Theme_DeviceDefault_Light)--设置主题\
activity.getWidth()--获取屏幕宽\
activity.getHeight()--获取屏幕高\
activity.newActivity(\"main\")--跳转页面\
activity.finish()--关闭当前页面\
activity.recreate()--重构activity\
os.exit()--结束程序\
tostring()--转换字符串\
tonumber()--转换数字\
tointeger()--转换整数\
--线程\
--thread\
thread(function()print\"线程\"end)\
--task\
task(function()print\"线程\"end)" ;
    },
    Intent类={
      --1
      "Intent（意图）主要是解决Android应用的各项组件之间的通讯。\
Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述.\
Android则根据此Intent的描述，负责找到对应的组件，将 Intent传递给调用的组件，并完成组件的调用。\
\
因此，Intent在这里起着一个媒体中介的作用\
专门提供组件互相调用的相关信息\
实现调用者与被调用者之间的解耦。\
\
例如，在一个联系人维护的应用中，当我们在一个联系人列表屏幕(假设对应的Activity为listActivity)上\
点击某个联系人后，希望能够跳出此联系人的详细信息屏幕(假设对应的Activity为detailActivity)\
为了实现这个目的，listActivity需要构造一个 Intent\
这个Intent用于告诉系统，我们要做“查看”动作，此动作对应的查看对象是“某联系人”\
然后调用startActivity (Intent intent)，将构造的Intent传入\
\
系统会根据此Intent中的描述到ManiFest中找到满足此Intent要求的Activity，系统会调用找到的 Activity，即为detailActivity，最终传入Intent，detailActivity则会根据此Intent中的描述，执行相应的操作。" ;
      --2
      "import \"android.content.Intent\"\
import \"android.app.SearchManager\"\
intent =  Intent()\
intent.setAction(Intent.ACTION_WEB_SEARCH)\
intent.putExtra(SearchManager.QUERY,\"Alua开发手册\")    \
activity.startActivity(intent)" ;
      --3
      "import \"android.content.Intent\"\
import \"android.net.Uri\"\
url=\"http://www.androlua.cn\"\
viewIntent =  Intent(\"android.intent.action.VIEW\",Uri.parse(url))\
activity.startActivity(viewIntent)" ;
      --4
      "packageName=程序包名\
import \"android.content.Intent\"\
import \"android.content.pm.PackageManager\"\
manager = activity.getPackageManager()\
open = manager.getLaunchIntentForPackage(packageName)\
this.startActivity(open)" ;
      --5
      "import \"android.content.Intent\"\
import \"android.net.Uri\"\
intent = Intent(Intent.ACTION_VIEW)\
安装包路径=\"/sdcard/a.apk\"\
intent.setDataAndType(Uri.parse(\"file://\"..安装包路径), \"application/vnd.android.package-archive\") \
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\
activity.startActivity(intent)" ;
      --6
      "import \"android.net.Uri\"\
import \"android.content.Intent\"\
包名=\"com.huluxia.gametools\"\
uri = Uri.parse(\"package:\"..包名)\
intent =  Intent(Intent.ACTION_DELETE,uri)\
activity.startActivity(intent)" ;
      --7
      "import \"android.content.Intent\"\
import \"android.net.Uri\"\
intent =  Intent(Intent.ACTION_VIEW)\
uri = Uri.parse(\"file:///sdcard/a.mp4\") \
intent.setDataAndType(uri, \"video/mp4\")\
activity.startActivity(intent)" ;
      --8
      "import \"android.content.Intent\"\
import \"android.net.Uri\"\
intent =  Intent(Intent.ACTION_VIEW)\
uri = Uri.parse(\"file:///sdcard/song.mp3\")\
intent.setDataAndType(uri, \"audio/mp3\")\
this.startActivity(intent)" ;
      --9
      "import \"android.content.Intent\"\
import \"android.net.Uri\"\
intent = Intent(\"android.intent.action.VIEW\")\
intent .setData(Uri.parse( \"market://details?id=\"..activity.getPackageName()))\
this.startActivity(intent)" ;
      --10
      "import \"android.content.Intent\"\
import \"android.provider.Settings\"\
intent = Intent(android.provider.Settings.ACTION_SETTINGS)\
this.startActivity(intent)\
\
字段列表:\
ACTION_SETTINGS\9系统设置\
CTION_APN_SETTINGS APN设置\
ACTION_LOCATION_SOURCE_SETTINGS 位置和访问信息\
ACTION_WIRELESS_SETTINGS 网络设置\
ACTION_AIRPLANE_MODE_SETTINGS 无线和网络热点设置\
ACTION_SECURITY_SETTINGS 位置和安全设置\
ACTION_WIFI_SETTINGS 无线网WIFI设置\
ACTION_WIFI_IP_SETTINGS 无线网IP设置\
ACTION_BLUETOOTH_SETTINGS 蓝牙设置\
ACTION_DATE_SETTINGS 时间和日期设置\
ACTION_SOUND_SETTINGS 声音设置\
ACTION_DISPLAY_SETTINGS 显示设置——字体大小等\
ACTION_LOCALE_SETTINGS 语言设置\
ACTION_INPUT_METHOD_SETTINGS 输入法设置\
ACTION_USER_DICTIONARY_SETTINGS 用户词典\
ACTION_APPLICATION_SETTINGS 应用程序设置\
ACTION_APPLICATION_DEVELOPMENT_SETTINGS 应用程序设置\
ACTION_QUICK_LAUNCH_SETTINGS 快速启动设置\
ACTION_MANAGE_APPLICATIONS_SETTINGS 已下载（安装）软件列表\
ACTION_SYNC_SETTINGS 应用程序数据同步设置\
ACTION_NETWORK_OPERATOR_SETTINGS 可用网络搜索\
ACTION_DATA_ROAMING_SETTINGS 移动网络设置\
ACTION_INTERNAL_STORAGE_SETTINGS 手机存储设置\
" ;
      --11
      "function OpenFile(path)\
  import \"android.webkit.MimeTypeMap\"\
  import \"android.content.Intent\"\
  import \"android.net.Uri\"\
  import \"java.io.File\"\
  FileName=tostring(File(path).Name)\
  ExtensionName=FileName:match(\"%.(.+)\")\
  Mime=MimeTypeMap.getSingleton().getMimeTypeFromExtension(ExtensionName)\
  if Mime then \
    intent = Intent()\
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\
    intent.setAction(Intent.ACTION_VIEW); \
    intent.setDataAndType(Uri.fromFile(File(path)), Mime); \
    activity.startActivity(intent)\
return true\
  else\
    return false\
  end\
end\
OpenFile(文件路径)" ;
      --12
      "import \"android.content.Intent\"\
  local intent= Intent(Intent.ACTION_PICK)\
  intent.setType(\"image/*\")\
  this.startActivityForResult(intent, 1)\
-------\
\
--回调\
function onActivityResult(requestCode,resultCode,intent)\
  if intent then\
    local cursor =this.getContentResolver ().query(intent.getData(), nil, nil, nil, nil)\
    cursor.moveToFirst()\
import \"android.provider.MediaStore\"\
    local idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA)\
    fileSrc = cursor.getString(idx)\
    bit=nil\
    --fileSrc回调路径路径\
import \"android.graphics.BitmapFactory\"\
    bit =BitmapFactory.decodeFile(fileSrc)\
  --  iv.setImageBitmap(bit)\
  end\
end--nirenr" ;
      --13
      "function ChooseFile()\
import \"android.content.Intent\"\
import \"android.net.Uri\"\
import \"java.net.URLDecoder\"\
import \"java.io.File\"\
intent = Intent(Intent.ACTION_GET_CONTENT)\
intent.setType(\"*/\");\
intent.addCategory(Intent.CATEGORY_OPENABLE)\
activity.startActivityForResult(intent,1);\
function onActivityResult(requestCode,resultCode,data)\
  if resultCode == Activity.RESULT_OK then\
  local str = data.getData().toString()\
  local decodeStr = URLDecoder.decode(str,\"UTF-8\")\
  print(decodeStr)\
  end\
end\
end\
\
ChooseFile()" ;
      --14
      "function Sharing(path)\
  import \"android.webkit.MimeTypeMap\"\
  import \"android.content.Intent\"\
  import \"android.net.Uri\"\
  import \"java.io.File\"\
  FileName=tostring(File(path).Name)\
  ExtensionName=FileName:match(\"%.(.+)\")\
  Mime=MimeTypeMap.getSingleton().getMimeTypeFromExtension(ExtensionName)\
  intent = Intent()\
  intent.setAction(Intent.ACTION_SEND)\
  intent.setType(Mime)\
  file = File(path)\
  uri = Uri.fromFile(file)\
  intent.putExtra(Intent.EXTRA_STREAM,uri)\
  intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\
  activity.startActivity(Intent.createChooser(intent, \"分享到:\"))\
end\
\
Sharing(文件路径)" ;
      --15
      "import \"android.net.Uri\"\
import \"android.content.Intent\"\
uri = Uri.parse(\"smsto:10010\")\
intent = Intent(Intent.ACTION_SENDTO, uri)\
intent.putExtra(\"sms_body\",\"cxll\") \
intent.setAction(\"android.intent.action.VIEW\")\
activity.startActivity(intent)" ;
      --16
      "import \"android.net.Uri\"\
import \"android.content.Intent\"\
uri=Uri.parse(\"file:///sdcard/a.png\") --图片路径\
intent= Intent();\
intent.setAction(Intent.ACTION_SEND);\
intent.putExtra(\"address\",mobile) --邮件地址\
intent.putExtra(\"sms_body\",content) --邮件内容\
intent.putExtra(Intent.EXTRA_STREAM,uri)\
intent.setType(\"image/png\") --设置类型\
this.startActivity(intent)" ;
      --17
      "import \"android.net.Uri\"\
import \"android.content.Intent\"\
uri = Uri.parse(\"tel:10010\")\
intent = Intent(Intent.ACTION_CALL, uri)\
intent.setAction(\"android.intent.action.VIEW\")\
activity.startActivity(intent)" ;
    },
    AndroLua帮助={
      --1
      "AndroLua是基于LuaJava开发的安卓平台轻量级脚本编程语言工具，既具有Lua简洁优雅的特质，又支持绝大部分安卓API，可以使你在手机上快速编写小型应用。\
官方QQ群：236938279；官方QQ2群：621400904\
百度贴吧：\
http://c.tieba.baidu.com/mo/m?kw=androlua\
项目地址：\
https://github.com/nirenr/AndroLua_pro\
打开链接支持nirenr的工作，一块也可以哦：\
https://qr.alipay.com/apt7ujjb4jngmu3z9a\
\
AndroLua使用了以下开源项目部分代码\
\
bson,crypt,md5\
https://github.com/cloudwu/skynet\
\
cjson\
https://sourceforge.net/projects/cjson/\
\
zlib\
https://github.com/brimworks/lua-zlib\
\
xml\
https://github.com/chukong/quick-cocos2d-x\
\
luv\
https://github.com/luvit/luv\
https://github.com/clibs/uv\
\
zip\
https://github.com/brimworks/lua-zip\
https://github.com/julienr/libzip-android\
\
luagl\
http://luagl.sourceforge.net/\
\
luasocket\
https://github.com/diegonehab/luasocket\
\
sensor\
https://github.com/ddlee/AndroidLuaActivity\
\
canvas\
由落叶似秋开发\
\
jni\
由nirenr开发" ;
      --2
      "工程结构\
  init.lua 工程配置文件\
  main,lua 工程主入口文件\
  layout.aly  工程默认创建的布局文件\
\
  菜单功能\
  三角形 运行：执行当前工程\
  左箭头 撤销：撤销输入的内容\
  右箭头 重做：恢复撤销的内容\
  打开：打开文件，在文件列表长按可删除文件\
  最近：显示最近打开过的文件\
\
  文件\
    保存：保存当前文件\
    新建：新建lua代码文件或者aly布局文件，代码文件与布局文件文件名不可以相同\
    编译：把当前文件编译为luac文件，通常用不到\
\
  工程\
    代开：在工程列表打开工程\
    打包：将当前工程编译为apk，默认使用debug签名\
    新建：新建一个工程\
    导出：将当前工程备份为alp文件\
    属性：编辑当前工程的属性，如 名称 权限等\
\
  代码\
    格式化：重新缩进当前文件使其更加便于阅读\
    导入分析：分析当前文件及引用文件需要导入的java类\
    查错：检查当前文件是否有语法错误\
\
  转到\
    搜索：搜索指定内容位置\
    转到：按行号跳转\
    导航：按函数跳转\
\
  插件：使用安装的插件\
\
  其他\
    布局助手：在编辑器打开aly文件时用于设计布局，目前功能尚不完善\
    日志：查看程序运行时的日志\
    java浏览器：用于查看java类的方法\
    手册：离线版lua官方手册\
    联系作者：加入官方qq群与作者交流\
    捐赠：使用支付宝捐赠作者，使软件更好的发展下去" ;
      --3
      "AndroLua是一个使用Lua语法编写可以使用安卓API的轻型脚本编程工具，使用它可以快速编写安卓应用。\
   第一次打开程序默认创建new.lua，并添加以下代码\
\
   require \"import\"\
   import \"android.widget.\"\
   import \"android.view.\"\
\
   require \"import\" 是导入import模块，该模块集成了很多实用的函数，可以大幅度减轻写代码负担，详细函数说明参考程序帮助。\
   import \"android.widget.*\" 是导入Java包。\
   这里导入了android的widget和view两个包。\
\
   导入包后使用类是很容易的，新建类实例和调用Lua的函数一样。\
   比如新建一个TextView\
   tv=TextView(activity)\
   activity表示当前活动的context。\
   同理新建按钮 btn=Button(activity)\
\
   给视图设置属性也非常简单\
   btn.text=\"按钮\"\
   btn.backgroundColor=0xff0000ff\
\
   添加视图事件回调函数\
   btn.onClick=function(v)\
     print(v)\
   end\
   函数参数v是视图本身。\
\
   安卓的视图需要添加到布局才能显示到活动，一般我们常用LinearLayout\
   layout=LinearLayout(activity)\
\
   用addView添加视图\
   layout.addView(btn)\
\
   最后调用activity的setContentView方法显示内容\
   activity.setContentView(layout)\
   这里演示androlua基本用法，通常我们需要新建一个工程来开发，代码的用法是相同的，具体细节请详细阅读后面的内容。" ;
      --4
      "打开了部分兼容选项，module，unpack，bit32\
添加string.gfind函数，用于递归返回匹配位置\
增加tointeger函数，强制将数值转为整数\
修改tonumber支持转换Java对象" ;
      --5
      "关于lua的语法和Android API请参考以下网页。\
Lua官网：\
http://www.lua.org\
Android 中文API：\
http://android.toolib.net/reference/packages.html" ;
      --6
      "require \"import\" \
以导入import模块，简化写代码的难度。\
目前程序还内置bmob,bson,canvas,cjson,crypt,ftp,gl,http,import,md5,smtp,socket,sensor,xml,zip,zlib等模块。\
一般模块导入形式\
local http=require \"http\"\
这样导入的是局部变量\
导入import后也可以使用\
import \"http\"\
的形式，导入为全局变量" ;
      --7
      "在使用Java类之前需要导入相应的包或者类，\
可以用包名.*的形式导入导入包\
import \"android.widget.*\"\
或者用完整的类名导入类\
import \"android.widget.Button\"\
导入内部类\
import \"android.view.View_OnClickListener\"\
或者在导入类后直接使用内部类\
View.OnClickListene\
包名和类名必须用引号包围。\
导入的类为全局变量，你可以使用\
local Burton=import \"android.widget.Button\"\
的形式保存为局部变量，以解决类名冲突问题。" ;
      --8
      "安卓使用布局与视图管理和显示用户界面。\
布局负责管理视图如何显示，如LinearLayout以线性排列视图，FrameLayout则要求自行指定停靠与位置。\
视图则显示具体内容，如TextView可以向用户展示文字内容，Button可以响应用户点击事件。\
\
创建一个线性布局\
layout=LinearLayout(activity)\
创建一个按钮视图\
button=Button(activity)\
将按钮添加到布局\
layout.addView(button)\
将刚才的内容设置为活动内容视图\
activity.setContentView(layout)\
\
注.activity是当前窗口的Context对象，如果你习惯也可以使用this\
button=Button(this)" ;
      --9
      "button.setText(\"按钮\")\
\
getter/setter\
Java的getxxx方法没有参数与setxxx方法只有一个参数时可以简写，\
button.Text=\"按钮\"\
x=button.Text" ;
      --10
      "创建事件处理函数\
function click(s)\
    print(\"点击\")\
    end\
把函数添加到事件接口\
listener=View.OnClickListener{onClick = click}\
把接口注册到组件\
button.setOnClickListener(listener)\
\
也可以使用匿名函数\
button.setOnClickListener(View.OnClickListener {onClick = function(s)\
        print(\"点击\")\
        end\
    })\
    \
onxxx事件可以简写\
button.onClick=function(v)\
    print(v)\
    end" ;
      --11
      "在活动文件添加以下函数，这些函数可以在活动的特定状态执行。\
function main(...)\
    --...：newActivity传递过来的参数。\
    print(\"入口函数\",...)\
    end\
\
function onCreate()\
    print(\"窗口创建\")\
    end\
\
function onStart()\
    print(\"活动开始\")\
    end\
  \
function onResume()\
    print(\"返回程序\")\
    end\
\
function onPause()\
    print(\"活动暂停\")\
    end\
\
function onStop()\
    print(\"活动停止\")\
    end\
\
function onDestroy()\
    print(\"程序已退出\")\
    end\
\
function onResult(name,...)\
  --name：返回的活动名称\
  --...：返回的参数\
  print(\"返回活动\",name,...)\
  end\
\
function onCreateOptionsMenu(menu)\
    --menu：选项菜单。\
    menu.add(\"菜单\")\
    end\
\
function onOptionsItemSelected(item)\
    --item：选中的菜单项\
    print(item.Title)\
    end\
\
function onConfigurationChanged(config)\
    --config：配置信息\
    print(\"屏幕方向关闭\")\
    end\
  \
function onKeyDown(keycode,event)\
    --keycode：键值\
    --event：事件\
    print(\"按键按下\",keycode)\
    end\
\
function onKeyUp(keycode,event)\
    --keycode：键值\
    --event：事件\
    print(\"按键抬起\",keycode)\
    end\
\
function onKeyLongPress(keycode,event)\
    --keycode：键值\
    --event：事件\
    print(\"按键长按\",keycode)\
    end\
\
function onTouchEvent(event)\
    --event：事件\
    print(\"触摸事件\",event)\
    end" ;
      --12
      "function onKeyDown(code,event)\
    print(code event)\
    end\
function onTouchEvent(event)\
    print(event)\
    end\
支持onKeyDown,onKeyUp,onKeyLongPress,onTouchEvent\
函数必须返布尔值" ;
      --13
      "array=float{1,2,3}\
或者\
array=int[10]\
a=array[0]\
array[0]=4" ;
      --14
      "需导入import模块，参看thread,timer与task函数说明。\
线程中使用独立环境运行，不能使用外部变量与函数，需要使用参数和回调与外部交互。\
任务\
\
task(str,args,callback)\
\
str 为任务执行代码，args 为参数，callback 为回调函数，任务返回值将传递到回调方法\
线程\
\
t=thread(str,args)\
\
str 为线程中执行的代码，args 为初始传入参数\
调用线程中方法\
call(t,fn,args)\
t 为线程，fn 为方法名称，args 为参数\
设置线程变量\
set(t,fn,arg)\
t 为线程，fn 为变量名称，arg 为变量值\
线程调用主线程中方法\
call(fn,args)\
fn 为方法名称，args 为参数\
线程设置主线程变量\
set(fn,arg)\
fn 为变量名称，arg 为变量值\
\
注. 参数类型为 字符串，数值，Java对象，布尔值与nil\
线程要使用quit结束线程。\
\
t=timer(func,delay,period,args)\
\
func 为定时器执行的函数，delay 为定时器延时，period 为定时器间隔，args 为初始化参数\
t.Enable=false 暂停定时器\
t.Enable=true 启动定时器\
t.stop() 停止定时器\
\
注意：定时器函数定义run函数时定时器重复执行run函数，否则重复执行构建时的func函数" ;
      --15
      "使用布局表须导入android.view与android.widget包。\
require \"import\"\
import \"android.widget.*\"\
import \"android.view.*\"\
布局表格式\
layout={\
    控件类名称,\
    id=控件名称,\
    属性=值,\
    {\
        子控件类名称,\
        id=控件名称,\
        属性=值,\
        }\
    }\
  \
例如：\
layout={\
  LinearLayout,--视图类名称\
  id=\"linear\",--视图ID，可以在loadlayout后直接使用\
  orientation=\"vertical\",--属性与值\
  {\
    TextView,--子视图类名称\
    text=\"hello AndroLua+\",--属性与值\
    layout_width=\"fill\"--布局属性\
  },\
}\
使用loadlayout函数解析布局表生成布局。\
activity.setContentView(loadlayout(layout))\
也可以简化为：\
activity.setContentView(layout)\
如果使用单独文件布局(比如有个layout.aly布局文件)也可以简写为：\
activity.setContentView(\"layout\")\
此时不用导入布局文件。\
\
布局表支持大全部安卓控件属性，\
与安卓XML布局文件的不同点：\
id表示在Lua中变量的名称，而不是安卓的可以findbyid的数字id。\
ImageView的src属性是当前目录图片名称或绝对文件路径图片或网络上的图片，\
layout_width与layout_height的值支持fill与wrap简写，\
onClick值为lua函数或java onClick接口或他们的全局变量名称，\
背景background支持背景图片，背景色与LuaDrawable自绘制背景，背景图片参数为是当前目录图片名称或绝对文件路径图片或网络上的图片，颜色同backgroundColor，自绘制背景参数为绘制函数或绘制函数的全局变量名称，\
控件背景色使用backgroundColor设置，值为\"十六进制颜色值\"。\
尺寸单位支持 px，dp，sp，in，mm，%w，%h。\
其他参考loadlayout与loadbitmap" ;
      --16
      "require \"import\"\
import \"android.app.*\"\
import \"android.os.*\"\
import \"android.widget.*\"\
import \"android.view.*\"\
import \"android.graphics.*\"\
activity.setTitle('AndroLua')\
\
paint=Paint()\
paint.setARGB(100,0,250,0)\
paint.setStrokeWidth(20)\
paint.setTextSize(28)\
\
sureface = SurfaceView(activity);\
callback=SurfaceHolder_Callback{\
    surfaceChanged=function(holder,format,width,height)\
        end,\
    surfaceCreated=function(holder)\
        ca=holder.lockCanvas()\
        if (ca~=nil) then\
            ca.drawRGB(0,79,90);\
            ca.drawRect(0,0,200,300,paint)\
            end\
        holder.unlockCanvasAndPost(ca)\
        end,\
    surfaceDestroyed=function(holder)\
        end\
    }\
holder=sureface.getHolder()\
holder.addCallback(callback)\
activity.setContentView(sureface)" ;
      --17
      "在大多数情况下androlua可以很好的处理Lua与Java类型之间的自动转换，但是Java的数值类型有多种(double,float,long,int,short,byte)，而Lua只有number，在必要的情况下可以使用类型的强制转换。\
i=int(10)\
i就是一个Java的int类型数据\
d=double(10)\
d是一个Java的double类型\
在调用Java方法时androlua可以自动将Lua的table转换成Java的array，Map或interface\
Map类型可以像使用Lua表一样简便。\
map=HashMap{a=1,b=2}\
print(map.a)\
map.a=3\
取长度运算符#可以获取Java中array，List,Map,Set，String的长度。" ;
      --18
      "require \"import\"\
import \"canvas\"\
import \"android.app.*\"\
import \"android.os.*\"\
import \"android.widget.*\"\
import \"android.view.*\"\
import \"android.graphics.*\"\
activity.setTitle('AndroLua')\
\
paint=Paint()\
paint.setARGB(100,0,250,0)\
paint.setStrokeWidth(20)\
paint.setTextSize(28)\
\
sureface = SurfaceView(activity);\
callback=SurfaceHolder_Callback{\
    surfaceChanged=function(holder,format,width,height)\
        end,\
    surfaceCreated=function(holder)\
        ca=canvas.lockCanvas(holder)\
        if (ca~=nil) then\
            ca:drawRGB(0,79,90)\
            ca:drawRect(0,0,200,300,paint)\
            end\
        canvas.unlockCanvasAndPost(holder,ca)\
        end,\
    surfaceDestroyed=function(holder)\
        end\
    }\
holder=sureface.getHolder()\
holder.addCallback(callback)\
activity.setContentView(sureface)" ;
      --19
      "require \"import\"\
import \"gl\"\
import \"android.app.*\"\
import \"android.os.*\"\
import \"android.widget.*\"\
import \"android.view.*\"\
import \"android.opengl.*\"\
activity.setTitle('AndroLua')\
--activity.setTheme( android.R.style.Theme_Holo_Light_NoActionBar_Fullscreen)\
\
mTriangleData ={\
    0.0, 0.6, 0.0,\
    -0.6, 0.0, 0.0,\
    0.6, 0.0, 0.0,\
    };\
mTriangleColor = {\
    1, 0, 0, 0,\
    0, 1, 0, 0,\
    0, 0, 1, 0,\
    };\
\
sr=GLSurfaceView.Renderer{\
    onSurfaceCreated=function(gl2, config)\
        gl.glDisable(gl.GL_DITHER);\
        gl.glHint(gl.GL_PERSPECTIVE_CORRECTION_HINT, gl.GL_FASTEST);\
        gl.glClearColor(0, 0, 0, 0);\
        gl.glShadeModel(gl.GL_SMOOTH);\
        gl.glClearDepth(1.0)\
        gl.glEnable(gl.GL_DEPTH_TEST);\
        gl.glDepthFunc(gl.GL_LEQUAL);\
        end,\
    onDrawFrame=function(gl2, config)\
        gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT);\
        gl.glMatrixMode(gl.GL_MODELVIEW);\
        gl.glLoadIdentity();\
        gl.glRotate(0,1,1,1)\
        gl.glTranslate(0, 0,0);\
        gl.glEnableClientState(gl.GL_VERTEX_ARRAY);\
        gl.glEnableClientState(gl.GL_COLOR_ARRAY);\
        gl.glVertexPointer( mTriangleData,3);\
        gl.glColorPointer(mTriangleColor,4);\
        gl.glDrawArrays( gl.GL_TRIANGLE_STRIP , 0, 3);\
        gl.glFinish();\
        gl.glDisableClientState(gl.GL_VERTEX_ARRAY);\
        gl.glDisableClientState(gl.GL_COLOR_ARRAY);\
        end,\
    onSurfaceChanged= function (gl2, w, h)\
        gl.glViewport(0, 0, w, h);\
        gl.glLoadIdentity();\
        ratio =  w / h;\
        gl.glFrustum(-rautio, ratio, -1, 1, 1, 10);\
        end\
    }\
\
glSurefaceView = GLSurfaceView(activity);\
glSurefaceView.setRenderer(sr);\
activity.setContentView(glSurefaceView);" ;
      --20
      "body,cookie,code,headers=http.get(url [,cookie,ua,header])\
body,cookie,code,headers=http.post(url ,postdata [,cookie,ua,header])\
code,headers=http.download(url [,cookie,ua,ref,header])\
body,cookie,code,headers=http.upload(url ,datas ,files [,cookie,ua,header])\
参数说明\
url 网址\
postdata post的字符串或字符串数据组表\
datas upload的字符串数据组表\
files upload的文件名数据表\
cookie 网页要求的cookie\
ua 浏览器识别\
ref 来源页网址\
header http请求头\
\
require \"import\"\
import \"http\"\
\
--get函数以get请求获取网页，参数为请求的网址与cookie\
body,cookie,code,headers=http.get(\"http://www.androlua.com\")\
\
--post函数以post请求获取网页，通常用于提交表单，参数为请求的网址，要发送的内容与cookie\
body,cookie,code,headers=http.post(\"http://androlua.com/Login.Asp?Login=Login&Url=http://androlua.com/bbs/index.asp\",\"name=用户名&pass=密码&ki=1\")\
\
--download函数和get函数类似，用于下载文件，参数为请求的网址，保存文件的路径与cookie\
http.download(\"http://androlua.com\",\"/sdcard/a.txt\")\
\
--upload用于上传文件，参数是请求的网址，请求内容字符串部分，格式为以key=value形式的表，请求文件部分，格式为key=文件路径的表，最后一个参数为cookie\
http.upload(\"http://androlua.com\",{title=\"标题\",msg=\"内容\"},{file1=\"/sdcard/1.txt\",file2=\"/sdcard/2.txt\"})" ;
      --21
      "require \"import\"\
import \"android.widget.*\"\
import \"android.view.*\"\
layout={\
    LinearLayout,\
    orientation=\"vertical\",\
    {\
        EditText,\
        id=\"edit\",\
        layout_width=\"fill\"\
        },\
    {\
        Button,\
        text=\"按钮\",\
        layout_width=\"fill\",\
        onClick=\"click\"\
        }\
    }\
\
function click()\
    Toast.makeText(activity, edit.getText().toString(), Toast.LENGTH_SHORT ).show()\
    end\
activity.setContentView(loadlayout(layout))" ;
      --22
      "获取内容 get函数\
Http.get(url,cookie,charset,header,callback)\
url 网络请求的链接网址\
cookie 使用的cookie，也就是服务器的身份识别信息\
charset 内容编码\
header 请求头\
callback 请求完成后执行的函数\
\
除了url和callback其他参数都不是必须的\
\
回调函数接受四个参数值分别是\
code 响应代码，2xx表示成功，4xx表示请求错误，5xx表示服务器错误，-1表示出错\
content 内容，如果code是-1，则为出错信息\
cookie 服务器返回的用户身份识别信息\
header 服务器返回的头信息\
\
向服务器发送数据 post函数\
Http.post(url,data,cookie,charset,header,callback)\
除了增加了一个data外，其他参数和get完全相同\
data 向服务器发送的数据\
\
下载文件 download函数\
Http.download(url,path,cookie,header,callback)\
参数中没有编码参数，其他同get，\
path 文件保存路径\
\
需要特别注意一点，只支持同时有127个网络请求，否则会出错\
\
\
Http其实是对Http.HttpTask的封装，Http.HttpTask使用的更加通用和灵活的形式\
参数格式如下\
Http.HttpTask( url, String method, cookie, charset, header,  callback) \
所有参数都是必选，没有则传入nil\
\
url 请求的网址\
method 请求方法可以是get，post，put，delete等\
cookie 身份验证信息\
charset 内容编码\
header 请求头\
callback 回调函数\
\
该函数返回的是一个HttpTask对象，\
需要调用execute方法才可以执行，\
t=Http.HttpTask(xxx)\
t.execute{data}\
\
注意调用的括号是花括号，内容可以是字符串或者byte数组，\
使用这个形式可以自己封装异步上传函数" ;
      --23
      "b=bmob(id,key)\
id 用户id，key 应用key。\
\
b:insert(key,data,callback)\
新建数据表，key 表名称，data 数据，callback 回调函数。\
\
b:update(key,id,data,callback)\
更新数据表，key 表名称id 数据id，data 数据，callback 回调函数。\
\
b:query(key,data,callback)\
查询数据表，key 表名称，data 查询规则，callback 回调函数。\
\
b:increment(key,id,k,v,c)\
原子计数，key 表名称，id 数据id，k 数据key，v 计数增加量。\
\
b:delete(key,id,callback)\
删除数据，key 表名称,id 数据id，callback 回调函数。\
\
b:sign(user,pass,mail,callback)\
注册用户，user 用户名，pass 密码，mail 电子邮箱，callback 回调函数。\
\
b:login(user or mail,pass,callback)\
登录用户，user 用户名，pass 密码，mail 电子邮箱，callback 回调函数。\
\
b:upload(path,callback)\
上传文件，path 文件路径，callback 回调函数。\
\
b:remove(url,callback)\
删除文件，url 文件路径，callback 回调函数。\
\
\
注：\
1，查询规则支持表或者json格式，具体用法参考官方api\
2，回调函数的第一个参数为状态码，-1 出错，其他状态码参考http状态码，第二个参数为返回内容。" ;
      --24
      "copyDir(from,to)\
复制文件或文件夹，from 源路径，to 目标路径。\
\
zip(from,dir,name)\
压缩文件或文件夹，from 源路径，dir 目标文件夹，name zip文件名称。\
\
unZip(from,to)\
解压文件，from zip文件路径，to 目标路径。\
\
getFileMD5(path)\
获取文件MD5值， path 文件路径。\
\
getFileSha1(path)\
获取文件Sha1值， path 文件路径。" ;
      --25
      "构建方法\
adapter=LuaAdapter(activity,data,layout)\
构建适配器，activity 当前活动，data 列表数据，layout 列表项目布局。\
data格式为{{id=value},{id=value}}格式的数组表。\
\
adapter.add(data)\
添加数据，data 为列表项目数据，格式为{id=value}。\
\
adapter.insert(idx,{id=value})\
插入数据，idx 为从0计数的插入位置，data 为列表项目数据，格式为{id=value}。\
\
adapter.remove(idx)\
删除数据，idx 为从0计数的删除位置。\
\
adapter.clear()\
清空数据。\
\
adapter.notifyDataSetChanged()\
更新数据。\
\
也可以使用table.insert/table.remove直接对data表操作，table库操作从1开始计数，改操作需要手动更新列表。\
\
在使用LuaAdapter的ListView的onItemClick/onItemLongClick回调函数中，第三个参数为从0开始的项目序号，第四个参数为从1开始的项目序号。" ;
      --26
      "新建工程或在脚本目录新建init.lua文件。\
写入以下内容，即可将文件夹下所有lua文件打包，main.lua为程序人口。\
appname=\"demo\"\
appver=\"1.0\"\
packagename=\"com.androlua.demo\"\
目录下icon.png替换图标，welcome.png替换启动图。\
打包使用debug签名。" ;
      --27
      "[a]表示参数a可选，(...)表示不定参数。函数调用在只有一个参数且参数为字符串或表时可以省略括号。\
AndroLua库函数在import模块，为便于使用都是全局变量。\
s 表示string类型，i 表示整数类型，n 表示浮点数或整数类型，t 表示表类型，b 表示布尔类型，o 表示Java对象类型，f为Lua函数。\
--表示注释。\
\
each(o)\
参数：o 实现Iterable接口的Java对象\
返回：用于Lua迭代的闭包\
作用：Java集合迭代器\
\
\
enum(o)\
参数：o 实现Enumeration接口的Java对象\
返回：用于Lua迭代的闭包\
作用：Java集合迭代器\
\
import(s)\
参数：s 要载入的包或类的名称\
返回：载入的类或模块\
作用：载入包或类或Lua模块\
import \"http\" --载入http模块\
import \"android.widget.*\" --载入android.widget包\
import \"android.widget.Button\" --载入android.widget.Button类\
import \"android.view.View$OnClickListener\" --载入android.view.View.OnClickListener内部类\
\
loadlayout(t [,t2])\
参数：t 要载入的布局表，t2 保存view的表\
返回：布局最外层view\
作用：载入布局表，生成view\
layout={\
    LinearLayout,\
    layout_width=\"fill\",\
    {\
        TextView,\
        text=\"Androlua\",\
        id=\"tv\"\
        }\
    }\
main={}\
activity.setContentView(loadlayout(layout,main))\
print(main.tv.getText())\
\
loadbitmap(s)\
参数：s 要载入图片的地址，支持相对地址，绝对地址与网址\
返回：bitmap对象\
作用：载入图片\
注意：载入网络图片需要在线程中进行\
\
task(s [,...], f)\
参数：s 任务中运行的代码或函数，... 任务传入参数，f 回调函数\
返回：无返回值\
作用：在异步线程运行Lua代码，执行完毕在主线程调用回调函数\
注意：参数类型包括 布尔，数值，字符串，Java对象，不允许Lua对象\
function func(a,b)\
    require \"import\"\
    print(a,b)\
    return a+b\
    end\
task(func,1,2,print)\
\
thread(s[,...])\
参数：s 线程中运行的lua代码或脚本的相对路径(不加扩展名)或函数，... 线程初始化参数\
返回：返回线程对象\
作用：开启一个线程运行Lua代码\
注意：线程需要调用quit方法结束线程\
func=[[\
a,b=...\
function add()\
    call(\"print\",a+b)\
    end\
]]\
t=thread(func,1,2)\
t.add()\
\
timer(s,i1,i2[,...])\
参数：s 定时器运行的代码或函数，i1 前延时，i2 定时器间隔，... 定时器初始化参数\
返回：定时器对象\
作用：创建定时器重复执行函数\
function f(a)\
    function run()\
        print(a)\
        a=a+1\
        end\
    end\
\
t=timer(f,0,1000,1)\
t.Enabled=false--暂停定时器\
t.Enabled=true--重新定时器\
t.stop()--停止定时器\
\
luajava.bindClass(s)\
参数：s class的完整名称，支持基本类型\
返回：Java class对象\
作用：载入Java class\
Button=luajava.bindClass(\"android.widget.Button\")\
int=luajava.bindClass(\"int\")\
\
luajava.createProxy(s,t)\
参数：s 接口的完整名称，t 接口函数表\
返回：Java接口对象\
作用：创建Java接口\
onclick=luajava.createProxy(\"android.view.View$OnClickListener\",{onClick=function(v)print(v)end})\
\
luajava.createArray(s,t)\
参数：s 类的完整名称，支持基本类型，t 要转化为Java数组的表\
返回：创建的Java数组对象\
作用：创建Java数组\
arr=luajava.createArray(\"int\",{1,2,3,4})\
\
luajava.newInstance(s [,...])\
参数：s 类的完整名称，... 构建方法的参数\
作用：创建Java类的实例\
b=luajava.newInstance(\"android.widget.Button\",activity)\
\
luajava.new(o[,...])\
参数：o Java类对象，... 参数\
返回：类的实例或数组对象或接口对象\
作用：创建一个类实例或数组对象或接口对象\
注意：当只有一个参数且为表类型时，如果类对象为interface创建接口，为class创建数组，参数为其他情况创建实例\
b=luajava.new(Button,activity)\
onclick=luajava.new(OnClickListener,{onClick=function(v)print(v)end})\
arr=luajava.new(int,{1,2,3})\
(示例中假设已载入相关类)\
\
luajava.coding(s [,s2 [, s3]])\
参数：s 要转换编码的Lua字符串，s2 字符串的原始编码，s3 字符串的目标编码\
返回：转码后的Lua字符串\
作用：转换字符串编码\
注意：默认进行GBK转UTF8\
\
luajava.clear(o)\
参数：o Java对象\
返回：无\
作用：销毁Java对象\
注意：仅用于销毁临时对象\
\
luajava.astable(o)\
参数：o Java对象\
返回：Lua表\
作用：转换Java的Array List或Map为Lua表\
\
luajava.tostring(o)\
参数：o Java对象\
返回：Lua字符串\
作用：相当于 o.toString()" ;
      --28
      "setContentView(layout, env)\
设置布局表layout为当前activity的主视图，env是保存视图ID的表，默认是_G\
getLuaDir()\
返回脚本当前目录\
getLuaDir(name)\
返回脚本当前目录的子目录\
getLuaExtDir()\
返回Androlua在SD的工作目录\
getLuaExtDir(name)\
返回Androlua在SD的工作目录的子目录\
getWidth()\
返回屏幕宽度\
getHeight()\
返回屏幕高度，不包括状态栏与导航栏\
loadDex(path)\
加载当前目录dex或jar，返回DexClassLoader\
loadLib(path)\
加载当前目录c模块，返回载入后模块的返回值(通常是包含模块函数的包)\
registerReceiver(filter)\
注册一个广播接收者，当再次调用该方法时将移除上次注册的过滤器\
newActivity(req, path, enterAnim, exitAnim, arg)\
打开一个新activity，运行路径为path的Lua文件，其他参数为可选，arg为表，接受脚本为变长参数\
result{...}\
向来源activity返回数据，在源activity的onResult回调\
newTask(func[, update], callback)\
新建一个Task异步任务，在线程中执行func函数，其他两个参数可选，执行结束回调callback，在任务调用update函数时在UI线程回调该函数\
新建的Task在调用execute{}时通过表传入参数，在func以unpack形式接收，执行func可以返回多个值\
newThread(func, arg)\
新建一个线程，在线程中运行func函数，可以以表的形式传入arg，在func以unpack形式接收\
新建的线程调用start()方法运行，线程为含有loop线程，在当前activity结束后自动结束loop\
newTimer(func, arg)\
新建一个定时器，在线程中运行func函数，可以以表的形式传入arg，在func以unpack形式接收\
调用定时器的start(delay, period)开始定时器，stop()停止定时器，Enabled暂停恢复定时器，Period属性改变定时器间隔" ;
      --29
      "布局表支持属性字符串常量\
    -- android:drawingCacheQuality\
    auto=0,\
    low=1,\
    high=2,\
\
    -- android:importantForAccessibility\
    auto=0,\
    yes=1,\
    no=2,\
\
    -- android:layerType\
    none=0,\
    software=1,\
    hardware=2,\
\
    -- android:layoutDirection\
    ltr=0,\
    rtl=1,\
    inherit=2,\
    locale=3,\
\
    -- android:scrollbarStyle\
    insideOverlay=0x0,\
    insideInset=0x01000000,\
    outsideOverlay=0x02000000,\
    outsideInset=0x03000000,\
\
    -- android:visibility\
    visible=0,\
    invisible=1,\
    gone=2,\
\
    wrap_content=-2,\
    fill_parent=-1,\
    match_parent=-1,\
    wrap=-2,\
    fill=-1,\
    match=-1,\
\
    -- android:orientation\
    vertical=1,\
    horizontal= 0,\
\
    -- android:gravity\
    axis_clip = 8,\
    axis_pull_after = 4,\
    axis_pull_before = 2,\
    axis_specified = 1,\
    axis_x_shift = 0,\
    axis_y_shift = 4,\
    bottom = 80,\
    center = 17,\
    center_horizontal = 1,\
    center_vertical = 16,\
    clip_horizontal = 8,\
    clip_vertical = 128,\
    display_clip_horizontal = 16777216,\
    display_clip_vertical = 268435456,\
    --fill = 119,\
    fill_horizontal = 7,\
    fill_vertical = 112,\
    horizontal_gravity_mask = 7,\
    left = 3,\
    no_gravity = 0,\
    relative_horizontal_gravity_mask = 8388615,\
    relative_layout_direction = 8388608,\
    right = 5,\
    start = 8388611,\
    top = 48,\
    vertical_gravity_mask = 112,\
    end = 8388613,\
\
    -- android:textAlignment\
    inherit=0,\
    gravity=1,\
    textStart=2,\
    textEnd=3,\
    textCenter=4,\
    viewStart=5,\
    viewEnd=6,\
    \
    -- android:inputType\
    none=0x00000000,\
    text=0x00000001,\
    textCapCharacters=0x00001001,\
    textCapWords=0x00002001,\
    textCapSentences=0x00004001,\
    textAutoCorrect=0x00008001,\
    textAutoComplete=0x00010001,\
    textMultiLine=0x00020001,\
    textImeMultiLine=0x00040001,\
    textNoSuggestions=0x00080001,\
    textUri=0x00000011,\
    textEmailAddress=0x00000021,\
    textEmailSubject=0x00000031,\
    textShortMessage=0x00000041,\
    textLongMessage=0x00000051,\
    textPersonName=0x00000061,\
    textPostalAddress=0x00000071,\
    textPassword=0x00000081,\
    textVisiblePassword=0x00000091,\
    textWebEditText=0x000000a1,\
    textFilter=0x000000b1,\
    textPhonetic=0x000000c1,\
    textWebEmailAddress=0x000000d1,\
    textWebPassword=0x000000e1,\
    number=0x00000002,\
    numberSigned=0x00001002,\
    numberDecimal=0x00002002,\
    numberPassword=0x00000012,\
    phone=0x00000003,\
    datetime=0x00000004,\
    date=0x00000014,\
    time=0x00000024,\
    \
    --android:ellipsize\
    end　　  \
    start 　　\
    middle     \
    marquee\
\
相对布局rule\
    layout_above=2,\
    layout_alignBaseline=4,\
    layout_alignBottom=8,\
    layout_alignEnd=19,\
    layout_alignLeft=5,\
    layout_alignParentBottom=12,\
    layout_alignParentEnd=21,\
    layout_alignParentLeft=9,\
    layout_alignParentRight=11,\
    layout_alignParentStart=20,\
    layout_alignParentTop=10,\
    layout_alignRight=7,\
    layout_alignStart=18,\
    layout_alignTop=6,\
    layout_alignWithParentIfMissing=0,\
    layout_below=3,\
    layout_centerHorizontal=14,\
    layout_centerInParent=13,\
    layout_centerVertical=15,\
    layout_toEndOf=17,\
    layout_toLeftOf=0,\
    layout_toRightOf=1,\
    layout_toStartOf=16\
    \
\
\
尺寸单位\
    px=0,\
    dp=1,\
    sp=2,\
    pt=3,\
    in=4,\
    mm=5" ;
    },
    网络操作={
      --1
      [[--断开连接并关闭WiFi
import "android.content.Context"      
WiFi_Service = activity.Context.getSystemService(Context.WIFI_SERVICE)
WiFi_Service.disconnect()]],
      --2
      [[--开启/关闭WiFi
import "android.content.Context"
WiFi_Service = activity.Context.getSystemService(Context.WIFI_SERVICE)

--开启WiFi
WiFi_Service.setWifiEnabled(true)

--关闭WiFi
WiFi_Service.setWifiEnabled(false)]],
      --3
      [[--获取WiFi打开状态
import "android.content.Context"
WiFi_Service = activity.Context.getSystemService(Context.WIFI_SERVICE)
WiFi_Enabled = WiFi_Service.isWifiEnabled()
print(WiFi_Enabled)]],
      --4.
      [[--获取WiFi信息
--该用法华为手机无法使用
import "android.content.Context"
WiFi_Service = activity.Context.getSystemService(Context.WIFI_SERVICE)
WiFi_Information = WiFi_Service.getConfiguredNetworks()
print(WiFi_Information)]],
      --5
      [[--获取WiFi状态
import "android.content.Context"
WiFi_Service = activity.Context.getSystemService(Context.WIFI_SERVICE)
WiFi_Status = WiFi_Service.getWifiState()
print(WiFi_Status)]],
      --6
      [[--获取WiFi加密类型
--该用法华为手机无法使用
ConfiguredNetworks = activity.Context.getSystemService(Context.WIFI_SERVICE).getConfiguredNetworks()
WiFi_KeyMgmt = string.match(tostring(ConfiguredNetworks),'KeyMgmt: (.-) P')
print(WiFi_KeyMgmt)]],
      --7
      [[--获取DNS
import "android.content.Context"

--获取DNS1
wifi = activity.Context.getSystemService(Context.WIFI_SERVICE).getDhcpInfo()
dns1 = string.match(tostring(wifi),"dns1 (.-) dns2")

--获取DNS2
wifi = activity.Context.getSystemService(Context.WIFI_SERVICE).getDhcpInfo()
dns2 = string.match(tostring(wifi),"dns2 (.-) D")]],
      --8
      [[--获取WiFi信号强度
WiFi_Manager = activity.Context.getSystemService(Context.WIFI_SERVICE);
WiFi_Info = WiFi_Manager.getConnectionInfo();
WiFi_Rssi = WiFi_Info.getRssi() 
print(WiFi_Rssi)]],
      --9
      [[--查看某网站IP地址
address=InetAddress.getByName("www.10010.com");

--查看本机IP地址
address=InetAddress.getLocalHost();

--查看IP地址
wifi = activity.Context.getSystemService(Context.WIFI_SERVICE).getDhcpInfo()
string.match(tostring(wifi),"ipaddr(.-)gate")]],
      --10
      [[获取内容 get函数
Http.get(url,cookie,charset,header,callback)
url 网络请求的链接网址
cookie 使用的cookie，也就是服务器的身份识别信息
charset 内容编码
header 请求头
callback 请求完成后执行的函数

除了url和callback其他参数都不是必须的

回调函数接受四个参数值分别是
code 响应代码，2xx表示成功，4xx表示请求错误，5xx表示服务器错误，-1表示出错
content 内容，如果code是-1，则为出错信息
cookie 服务器返回的用户身份识别信息
header 服务器返回的头信息

向服务器发送数据 post函数
Http.post(url,data,cookie,charset,header,callback)
除了增加了一个data外，其他参数和get完全相同
data 向服务器发送的数据

下载文件 download函数
Http.download(url,path,cookie,header,callback)
参数中没有编码参数，其他同get，
path 文件保存路径

需要特别注意一点，只支持同时有127个网络请求，否则会出错


Http其实是对Http.HttpTask的封装，Http.HttpTask使用的更加通用和灵活的形式
参数格式如下
Http.HttpTask( url, String method, cookie, charset, header,  callback) 
所有参数都是必选，没有则传入nil

url 请求的网址
method 请求方法可以是get，post，put，delete等
cookie 身份验证信息
charset 内容编码
header 请求头
callback 回调函数

该函数返回的是一个HttpTask对象，
需要调用execute方法才可以执行，
t=Http.HttpTask(xxx)
t.execute{data}

注意调用的括号是花括号，内容可以是字符串或者byte数组，
使用这个形式可以自己封装异步上传函数]],
      --11
      [[import "android.net.TrafficStats"
getMobileRxBytes()  --获取通过Mobile连接收到的字节总数，不包含WiFi  
getMobileRxPackets()  --获取Mobile连接收到的数据包总数  
getMobileTxBytes()  --Mobile发送的总字节数  
getMobileTxPackets()  --Mobile发送的总数据包数  
getTotalRxBytes()  --获取总的接受字节数，包含Mobile和WiFi等  
getTotalRxPackets()  --总的接受数据包数，包含Mobile和WiFi等  
getTotalTxBytes()  --总的发送字节数，包含Mobile和WiFi等  
getTotalTxPackets()  --发送的总数据包数，包含Mobile和WiFi等   
getUidRxBytes(int uid)  --获取某个网络UID的接受字节数  
getUidTxBytes(int uid) --获取某个网络UID的发送字节数   
--例:TrafficStats.getTotalRxBytes()]],
      --12
      [[connManager = activity.getSystemService(Context.CONNECTIVITY_SERVICE)
    mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
    if tostring(mWifi):find("none)")  then
    --未连接
    else
    --连接
    end]],
      --13
      [[wifiManager=activity.Context.getSystemService(Context.WIFI_SERVICE);
wifiInfo=wifiManager.getConnectionInfo();
print(wifiInfo.getHiddenSSID())]],
      --14
      [[wifiManager=activity.Context.getSystemService(Context.WIFI_SERVICE);
wifiInfo=wifiManager.getConnectionInfo();
print(wifiInfo.getMacAddress())]],
      --15
      [[manager = activity.getSystemService(Context.CONNECTIVITY_SERVICE);  
gprs = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();  
if tostring(gprs)== "CONNECTED" then
print"当前数据网络"
end]],
      --16
      [[wifiManager=activity.Context.getSystemService(Context.WIFI_SERVICE);
wifiInfo=wifiManager.getConnectionInfo();
print(wifiInfo.getSSID())]],
    }

  }

}