1

今日、Android ソースでいくつかの実験を行っていました。

完全なことを教えてください.androidソースからframework.jarをコンパイルして逆コンパイルし、smaliソースを生成して脇に置いておきました。次に、CyanogenMod リポジトリから、機能のコミットを Android ソースに追加し、framework.jar をコンパイルして、smali ソースを何度も逆コンパイルして、smali に関する変更を確認し、ROM に移植できるようにしました。

私が移植しようとしている機能には、特定のクラスのインポートが必要です。たとえば、 import dalvik.system.VMRuntime と、それらのインポートされたクラスを利用するための追加のコーディングが必要です。だから今私の問題は、余分なコーディング、つまりsmaliコードでのそれらのクラスの使用しか見ることができず、それらのインポートを見ることができないということです。したがって、smali コードのみを移植すると、そのメソッドが見つからないことを示す java.lang.NoSuchMethodError が logcat に表示されます。必要なクラスがインポートされていないため、その理由は明らかです。次に、smali コードでそれを行う方法は? smali でそれを行う方法が見当たりません。そのため、新しく導入された方法が機能しません。

これに対する実行可能な解決策はありますか?

4

2 に答える 2

6

Java でインポートが行う唯一のことは、完全なパッケージ名を指定しなくてもクラスに言及できるようにすることです。smali では、インポートはありません。すべては、パッケージを含む完全修飾クラス名を常に使用します。

そのため、あなたの問題は間違いなく輸入とは関係ありません。デバイスに存在しないメソッドを使用しようとしているようです。

デバイスからフレームワーク jar を逆アセンブルし、の定義を見つけて、dalvik.system.VMRuntime使用可能なメソッドを確認できます。または、代わりにいくつかのリフレクション呼び出しを追加して、情報を logcat に記録します。

VMRuntime はパブリック API の一部ではないことに注意してください。また、すべてのデバイスまたは Android の将来のバージョンで存在または一貫しているとは限りません。

于 2013-03-17T19:14:50.650 に答える
1

(私はsmaliを知らないので、もっと良い解決策があるかもしれません)

import ステートメントを必要とする Java プログラムはありません。たとえば ArrayList を使用するには、それをインポートするか、java.util.ArrayList として完全に参照する必要があります。

たとえば、C++ #include と Java インポートの間には大きな違いがあります。C++ #include は、プログラムにコードを直接挿入します。通常は、使用しているクラスの宣言です。宣言を取得するプロセスは、Java では 2 つの段階に分けられます。最初に、コンパイラは完全修飾クラス名を決定し、次に独自のライブラリとクラスパスを使用してその名前の宣言を見つけます。Java インポートは、完全修飾クラス名の計算にのみ使用されるため、完全修飾名だけで参照されるクラスには必要ありません。

おそらく、追加するコードを前処理して、たとえば VMRuntime を dalvik.system.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 に答える