1

我今天在android源代码中做了一些实验。

让我说完整的事情,我从android源编译framework.jar并对其进行反编译并生成smali源并将其放在一边。然后从 CyanogenMod 存储库中,我向 android 源代码添加了一个功能的提交,并一次又一次地编译了 framework.jar 反编译的 smali 源代码,以查看 smali 方面的变化,以便我可以将它们移植到我的 ROM 中。

我要移植的功能需要导入某些类,例如 import dalvik.system.VMRuntime 和额外编码以使用这些导入的类。所以现在我的问题是,我只能看到额外的编码,即在 smali 代码中使用这些类,但看不到那些导入。因此,当我仅移植 smali 代码时,我在 logcat 中得到 java.lang.NoSuchMethodError,这表明它无法找到该方法。原因很清楚,因为没有导入必要的类,那么如何在 smali 代码中做到这一点?我认为在 smali 中没有办法做到这一点,因此新引入的方法不起作用。

有什么可行的解决方案吗?

4

2 回答 2

6

导入在 java 中所做的唯一事情就是使您可以提及一个类而无需指定完整的包名。在 smali 中,没有导入 - 一切都始终使用包含包的完全限定类名。

因此,您的问题绝对与进口无关。听起来您正在尝试使用设备上根本不存在的方法。

您可以从您的设备中反汇编框架 jar 并找到其定义dalvik.system.VMRuntime并查看可用的方法。或者添加一些反射调用并将信息记录到 logcat。

值得注意的是,VMRuntime 不是公共 API 的一部分,它可能不会在所有设备或未来版本的 Android 上都存在或一致。

于 2013-03-17T19:14:50.650 回答
1

(我不知道 smali,所以可能有更好的解决方案)

没有 Java 程序需要任何 import 语句。要使用例如 ArrayList,您需要导入它或完整引用它,如 java.util.ArrayList。

例如,C++ #include 和 Java 导入之间存在显着差异。C++ #include 直接在您的程序中插入代码,通常是您正在使用的类的声明。获取声明的过程在 Java 中分为两个阶段。首先编译器确定完全限定的类名,然后它使用自己的库和类路径来查找该名称的声明。Java 导入仅用于计算完全限定的类名,因此对于仅由其完全限定名引用的任何类都不需要。

也许您可以预处理要添加的代码,例如用 dalvik.system.VMRuntime 等替换 VMRuntime,这样您就可以在不导入的情况下编译它。

下面是一个以不同方式使用 java.util 类的短程序示例,没有任何导入:

public class Test {
  public static void main(String[] args) {
    java.util.List<String> list = new java.util.ArrayList<String>();
    list.add("bbb");
    list.add("aaa");
    java.util.Collections.sort(list);
    System.out.println(list);
  }
}
于 2013-03-17T13:44:01.527 回答