找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3592|回复: 0

动态生成dalvik字节码——dexmaker

[复制链接]

307

主题

228

回帖

7319

积分

用户组: 真·技术宅

UID
2
精华
76
威望
291 点
宅币
5569 个
贡献
253 次
宅之契约
0 份
在线时间
945 小时
注册时间
2014-1-25
发表于 2016-5-2 17:40:21 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
本帖最后由 元始天尊 于 2016-5-2 17:45 编辑

https://android.googlesource.com/platform/external/dexmaker.git
该开源项目可以通过编程的方式,把java语义直接转换成android上dalvik字节码,
正常的java代码编译生成class,而要转换成dalvik字节码才能给android使用,
这里介绍的黑科技就是比android上直接加载dex更为底层——直接在android上编译出dalvik字节码再加载
例:
我想生成如下java代码的dalvik字节码:


  1. package com.google.dexmaker.examples.Fibonacci;

  2. public class Fibonacci {
  3.    public static int fib(int i) {
  4.      if (i < 2) {
  5.        return i;
  6.      }
  7.      return fib(i - 1) + fib(i - 2);
  8.    }
  9. }
复制代码


那么我需要写一个对应的逻辑去在android中生成上述逻辑,下面的代码我称为预编译代码
  1.        
  2.         // 对应package com.google.dexmaker.examples.Fibonacci;
  3.         TypeId<?> fibonacci = TypeId.get("Lcom/google/dexmaker/examples/Fibonacci;");

  4.         String fileName = "Fibonacci.generated";
  5.         DexMaker dexMaker = new DexMaker();
  6.         //对应 public class Fibonacci
  7.         dexMaker.declare(fibonacci, fileName, Modifier.PUBLIC, TypeId.OBJECT);

  8.         //对应public static int fib(int i)
  9.         MethodId<?, Integer> fib = fibonacci.getMethod(TypeId.INT, "fib", TypeId.INT);
  10.         Code code = dexMaker.declare(fib, Modifier.PUBLIC | Modifier.STATIC);

  11.         //声明局部变量
  12.         Local<Integer> i = code.getParameter(0, TypeId.INT);
  13.         Local<Integer> constant1 = code.newLocal(TypeId.INT);
  14.         Local<Integer> constant2 = code.newLocal(TypeId.INT);
  15.         Local<Integer> a = code.newLocal(TypeId.INT);
  16.         Local<Integer> b = code.newLocal(TypeId.INT);
  17.         Local<Integer> c = code.newLocal(TypeId.INT);
  18.         Local<Integer> d = code.newLocal(TypeId.INT);
  19.         Local<Integer> result = code.newLocal(TypeId.INT);

  20.         code.loadConstant(constant1, 1);//=1
  21.         code.loadConstant(constant2, 2);//=2
  22.         Label baseCase = new Label();
  23.         code.compare(Comparison.LT, baseCase, i, constant2);//if (i < 2) {
  24.         code.op(BinaryOp.SUBTRACT, a, i, constant1);//fib(i - 1)
  25.         code.op(BinaryOp.SUBTRACT, b, i, constant2);//fib(i - 2)
  26.         code.invokeStatic(fib, c, a);
  27.         code.invokeStatic(fib, d, b);
  28.         code.op(BinaryOp.ADD, result, c, d);
  29.         code.returnValue(result);//return fib(i - 1) + fib(i - 2);
  30.         code.mark(baseCase);//}
  31.         code.returnValue(i);//return i

复制代码

全部代码
  1. /*
  2. * Copyright (C) 2012 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. *      [url]http://www.apache.org/licenses/LICENSE-2.0[/url]
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */

  16. package example;

  17. import com.google.dexmaker.BinaryOp;
  18. import com.google.dexmaker.Code;
  19. import com.google.dexmaker.Comparison;
  20. import com.google.dexmaker.DexMaker;
  21. import com.google.dexmaker.Label;
  22. import com.google.dexmaker.Local;
  23. import com.google.dexmaker.MethodId;
  24. import com.google.dexmaker.TypeId;
  25. import java.io.File;
  26. import java.lang.reflect.Method;
  27. import java.lang.reflect.Modifier;

  28. public final class FibonacciMaker {
  29.     public static void main(String[] args) throws Exception {
  30.         TypeId<?> fibonacci = TypeId.get("Lcom/google/dexmaker/examples/Fibonacci;");

  31.         String fileName = "Fibonacci.generated";
  32.         DexMaker dexMaker = new DexMaker();
  33.         dexMaker.declare(fibonacci, fileName, Modifier.PUBLIC, TypeId.OBJECT);

  34.         MethodId<?, Integer> fib = fibonacci.getMethod(TypeId.INT, "fib", TypeId.INT);
  35.         Code code = dexMaker.declare(fib, Modifier.PUBLIC | Modifier.STATIC);

  36.         Local<Integer> i = code.getParameter(0, TypeId.INT);
  37.         Local<Integer> constant1 = code.newLocal(TypeId.INT);
  38.         Local<Integer> constant2 = code.newLocal(TypeId.INT);
  39.         Local<Integer> a = code.newLocal(TypeId.INT);
  40.         Local<Integer> b = code.newLocal(TypeId.INT);
  41.         Local<Integer> c = code.newLocal(TypeId.INT);
  42.         Local<Integer> d = code.newLocal(TypeId.INT);
  43.         Local<Integer> result = code.newLocal(TypeId.INT);

  44.         code.loadConstant(constant1, 1);
  45.         code.loadConstant(constant2, 2);
  46.         Label baseCase = new Label();
  47.         code.compare(Comparison.LT, baseCase, i, constant2);
  48.         code.op(BinaryOp.SUBTRACT, a, i, constant1);
  49.         code.op(BinaryOp.SUBTRACT, b, i, constant2);
  50.         code.invokeStatic(fib, c, a);
  51.         code.invokeStatic(fib, d, b);
  52.         code.op(BinaryOp.ADD, result, c, d);
  53.         code.returnValue(result);
  54.         code.mark(baseCase);
  55.         code.returnValue(i);

  56.         ClassLoader loader = dexMaker.generateAndLoad(
  57.                 FibonacciMaker.class.getClassLoader(), getDataDirectory());

  58.         Class<?> fibonacciClass = loader.loadClass("com.google.dexmaker.examples.Fibonacci");
  59.         Method fibMethod = fibonacciClass.getMethod("fib", int.class);
  60.         System.out.println(fibMethod.invoke(null, 8));
  61.     }

  62.     public static File getDataDirectory() {
  63.         String envVariable = "ANDROID_DATA";
  64.         String defaultLoc = "/data";
  65.         String path = System.getenv(envVariable);
  66.         return path == null ? new File(defaultLoc) : new File(path);
  67.     }
  68. }
复制代码


应该可以建立一个翻译工具,将java代码翻译为上面的预编译代码,从而实现动态下载java代码,在android上运行
回复

使用道具 举报

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-3-29 21:52 , Processed in 0.032457 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表