今天我们来研究一下火山安卓的源代码，火山安卓允许我们以本地化编程（中文代码编程）的方式来撰写安卓 app，那么在生成实际要安装到安卓 app 的时候，它是如何进行编译处理的呢。让我们今天来一起探究一下。首先我们编写一个 app 内容，这个 app 由编辑框和按钮组成的窗口，我们要实现的是点击该按钮，就会弹出一个信息提示框，而这个信息提示框提示的内容就与编辑框中的内容一致。实现的效果类似这样：这很好实现，我就不贴窗口设计图了，大家不明白如何设计该窗口的可以看下我的源码即可，贴一下实现的源码：接下来我们来看一下生成的目录中 （前提是已经进行过调试或者生成发行版了），能否找到对应的文件。首先告知大家，我们的解决方案保存在 E:\voldevproject\xueshanlinghu_learn_voldev180 路径下。可以看到除了解决方案文件之外有几个项目文件夹，这些文件夹存放的都是该项目的火山源码文件、项目自己的资源等，方便管理。同时，如果你曾经调试过或者编译过发布版本的话，会看到一个 _int 的文件夹。我们可以双击打开该文件夹。里面是按照每个项目单独建立文件夹的。我们点击今天研究的项目的文件夹 javacode_day4 进入。可以看到一个“debug”文件夹，这个文件夹是通过“调试”功能生成的，生成的相关文件都存在里面，如果你曾经生成过发布版，则这里还能找到一个“release”文件夹，这里面存放的就是发布版本。再往下进去一层目录，大家的目录结构就基本一样了，我就不截图了，大家自己进去看。那么我们编写的源码放在哪里呢，我们可以在如下目录结构找到我们今天项目从火山源码转换成 java 源码后编译前的源码：E:\voldevproject\xueshanlinghu_learn_voldev180_int\javacode_day4\debug\project\src\xshlh\xhsh\day4\hshdmzhjavaydmchk\rg_qdl.java顺带一提，编译好的 apk 文件保存在如下路径下：E:\voldevproject\xueshanlinghu_learn_voldev180_int\javacode_day4\debug\linker再说回来，上述路径一直到 src 的层级是大家可以借鉴的，中间的 \xshlh\xhsh\day4\hshdmzhjavaydmchk 部分，是我们这个项目特有的，大家看一下像什么？是不是很像拼音？其实就是 包名 的拼音 声母 组合的文件夹层级。我们来看一下我们的包名是什么，我们这个项目的包名是：雪山凌狐.学火山.day4.火山代码转java源代码查看 。大家看一下 “雪山凌狐” 翻译成拼音是不是就是 “xshlh”？请注意这里它有一个处理特殊点，就是翘舌的字用的拼音是 sh，也就是声母，而不是用首字母 s，所以我们的目录层级是包名的拼音声母组合。我们知道在火山安卓中，当包名相同的时候，安装到安卓程序就会被视为同一个程序，所以我们的包名尽可能长一些特有一些就不容易重复。火山这种方式，我们发现可能存在着一个问题点，那就是如果是不同的汉字，包名我们在火山软件平台里面看起来当然不同，但是声母相同，在安装生成的时候，会不会变成相当于同一个程序呢？ 下节课我们来一起研究一下这个问题。如果是，其实建议火山平台今后的版本还需要在用户自己设置的包名基础上，加上随机字符之类的避免包名相同吧（或其他更高级的办法）。后面的 rg_qdl.java 就是源文件啦，可以看到是一个 java 文件咯。因此我们可以知道，火山的编译器相当于一个翻译器，编写后的中文代码，使用火山自带的编译器会转换成对应的 java 源代码，然后通过这些代码进行编译，最后生成我们的 apk 文件供安卓系统安装。接下来我们打开一下该 java 源文件看一下能不能看懂，同时我再贴一遍火山源码：package xshlh.xhsh.day4.hshdmzhjavaydmchk; import android.app.Activity; import android.view.View; import android.view.ViewGroup; import android.widget.*; public class rg_qdl extends hsh.anzh.jb.rg_chk { public rg_qdl () { } protected hsh.anzh.jb.rg_bjk rg_n14433; protected hsh.anzh.jb.rg_ann rg_n14434; protected hsh.anzh.jb.rg_xxbjq rp_1; @Override public hsh.anzh.jb.AndroidViewGroup GetAndroidActivityContainer () { return rp_1; } @Override protected boolean onInitAndroidActivity () { if (super.onInitAndroidActivity () == false) return false; setContentView (R.layout.rg_qdl); rp_1 = new hsh.anzh.jb.rg_xxbjq (this, (LinearLayout)findViewById (R.id.rg_qdl)); rp_1.onInitControlContent (this, null); rg_n14433 = new hsh.anzh.jb.rg_bjk (this, (EditText)findViewById (R.id.rg_n14433)); rg_n14433.onInitControlContent (this, null); rg_n14434 = new hsh.anzh.jb.rg_ann (this, (Button)findViewById (R.id.rg_n14434)); rg_n14434.onInitControlContent (this, null); rg_n14434.rl_AndroidView_n3017 (new hsh.anzh.jb.AndroidView.re_n3017 () { public int dispatch (hsh.anzh.jb.AndroidView objSource, int nTagNumber) { return rg_n14435 ((hsh.anzh.jb.rg_ann)objSource, nTagNumber); } }, 0); return true; } protected int rg_n14435 (hsh.anzh.jb.rg_ann rg_n14436, int rg_n14437) { if (rg_n14436 == rg_n14434) { rg_n15040 (String.valueOf (rg_n14433.GetTextView ().getText ())); } return (0); } }分析以上源码，我们可以首先知道这是一个包（package），然后里面的包名你还是很明显看出是声母组合的翻译。接下来就是一些引用和翻译，看不懂没关系，咱们来看最后的这部分吧：最后的这部分，可以看到有 if 语句，很明显不就是我们按钮_被单击事件方法中的内容吗？有的同学会问，比如 rg_n14436 是啥啊，完全看不懂，其实这是对应 “来源对象” 的 id，而同理 rg_n14434 就代表着该程序的那个按钮的 id。通过 id 可以唯一访问资源，对程序进行控制。那么在哪定义这些 id 的呢，其实我估计应该是随机生成的，然后对应关系是保存在其他文件夹的其他 java 源码当中，大家可以自己去探索，我们就不看了。可以看到，与我们中文代码逻辑一致，判断来源对象是否等于该按钮，如果是的话，就调用提示信息框的方法，对应 id 应该是看到的 rg_n15040。去获取编辑框 rg_n14433 的内容，用的是 getText() 方法。是不是很有趣？其实这也是学习对应 java 语句的挺好的办法，虽然你不一定懂，但能对照着中文代码去阅读，是不是感觉理解了许多？欢迎大家继续多写几段火山代码，然后再看看转换成 java 源代码后是如何实现的。最后附上咱们的源码下载地址：