10

わかりました、おそらくそれは非常に単純ですが、私は今それを理解することはできません.

Google サンプル プロジェクトCard Readerを Android Studio 1.5.1 にインポートしました。これは compileSdkVerison 23 でコンパイルされ、モバイルで動作します。

次に、SDK を調べながらソース コードをandroid.nfc.tech.BasicTagTechnologyに移動しました。TransceiveResult内部android.nfc.tech.BasicTagTechnology#transceiveで解決できないことがわかり、クラスTransceiveResultがにありませんがD:\Android\sdk\platforms\android-23\android.jar、ここに Android ソース コードD:\Android\sdk\sources\android-23\android\nfc\TransceiveResult.javaが表示されていることがわかりました。エクスポートされた、実際には

/**
 * Class used to pipe transceive result from the NFC service.
 *
 * @hide
 */

public final class TransceiveResult implements Parcelable

次に、プロジェクトを同期し、クリーンして再構築し、キャッシュを無効にする/再起動した後、いくつかのランダムなことを行いましたが、それでも解決できませんTransceiveResult.SDKでシンボルが失われたため、プロジェクトをどのようにコンパイルできるか疑問に思っていますスムーズに?

編集して、ついにああ

android.nfc.tech.BasicTagTechnology#transceiveではなくコードを呼び出しますTransceiveResult。コンパイル時に解決する必要はありません。コードで参照されているものTransceiveResultを解決するだけandroid.nfc.tech.BasicTagTechnology#transceiveで済みます。その瞬間、私は迷子になりました。

4

1 に答える 1

7

@hide は、ここで説明されているようにドキュメントに含まれていないことを意味し、コンパイルで使用される android.jar 内のクラスからも削除されます。ただし、これらは実行時に使用できます。

更新: SDK クラスを掘り下げるときに IDE で明確にするために、解決できない非表示のメンバーへの参照が表示される場合があります。これは問題ありません。これらがコード内ではなく SDK クラス内にある限り、コンパイルされます。

これらの非表示のクラス/メソッド/フィールドを使用する場合は、2 つの主なオプションがあります。

1) android-framework.jar のフル バージョンを取得し、コンパイルできるようにします。ただし、これには、クラスまたはメソッドが存在しない可能性があるため、コンパイルされたコードがおそらく他の Android バージョンで実行されないという欠点があります。また、たとえば BasicTagTechnology は実際にはパッケージプライベートであるため、とにかくそのようにアクセスすることはできません

2) リフレクションを使用する:

Class tr = Class.forName("android.nfc.TransceiveResult");
        Constructor constructor =
                tr.getConstructor(new Class[]{int.class, byte[].class});
        Object trObj = constructor.newInstance(1, new byte[]{1,2});

これは、より柔軟であり、クラス/メソッドが存在するかどうかを確認して、それらを初期化/呼び出し、例外などをキャッチできるという意味で、より良いオプションです.

于 2016-04-07T21:53:50.503 に答える