10

好吧,也许这很简单,但我现在想不通。

我在 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 回答