当 SDK 中缺少导入的类时,Android 项目如何编译? [英] How can Android project compile when imported class is missing in SDK?

查看:54
本文介绍了当 SDK 中缺少导入的类时,Android 项目如何编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

OK, perhaps it is very simple, but I just can not figure it out right now.

我在 Android Studio 1.5.1 中导入了谷歌示例项目 Card Reader,它在 compileSdkVerison 23 编译,它适用于我的手机.

I have imported google sample project Card Reader in Android Studio 1.5.1, it compiles at compileSdkVerison 23, it works on my Mobile.

然后我浏览了SDK,同时来到android.nfc.tech.BasicTagTechnology的源代码,我在android.nfc.tech中找到了TransceiveResult.BasicTagTechnology#transceive 无法解决,然后我发现 D:\Android\sdk\platforms\android-23\android.jar<中缺少 TransceiveResult 类/code>,但在此处的 Android 源代码中显示 D:\Android\sdk\sources\android-23\android\nfc\TransceiveResult.java 然后我意识到它可以对公共隐藏,而不是导出,其实是

Then I walked through the SDK while came to source code to android.nfc.tech.BasicTagTechnology, I found TransceiveResult inside android.nfc.tech.BasicTagTechnology#transceive couldn't not be resolved then I found the class TransceiveResult is missing in my D:\Android\sdk\platforms\android-23\android.jar, but presents in Android source code here D:\Android\sdk\sources\android-23\android\nfc\TransceiveResult.java then I realized it could be hidden from public, not exported, actually it is

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

public final class TransceiveResult implements Parcelable

然后我做了一些随机的事情,在我同步项目后,清理和重建,使缓存无效/重新启动,顺便说一下,仍然无法解析TransceiveResult,我想知道因为符号已经丢失在SDK中,项目如何顺利编译?

Then I have done some random things, after I have sync the project, clean and rebuild, invalidate caches / restarted, still not able to resolve TransceiveResult by the way, I am wondering since the symbol has been lost in SDK, how can the project compile smoothly?

编辑我终于啊哈

我们在代码中调用 android.nfc.tech.BasicTagTechnology#transceive 而不是 TransceiveResult,在编译时我们不需要解析 TransceiveResult,我们只需要解析我们代码中引用的android.nfc.tech.BasicTagTechnology#transceive,那一刻我迷路了.

We call android.nfc.tech.BasicTagTechnology#transceive in our code rather than TransceiveResult, in the compile-time we no need to resolve TransceiveResult, we only need to resolve android.nfc.tech.BasicTagTechnology#transceive which is referenced in our code, I was lost at that moment.

推荐答案

@hide 表示它不包含在文档中,如 here 并且它也从用于编译的 android.jar 中的类中删除.然而,这些在运行时可用.

@hide means its not included in the docs as described here and it is also stripped from the classes within your android.jar which is used in compilation. These however are available in runtime.

更新:为了在您深入研究 SDK 类时在 IDE 中进行澄清,您可能会看到对无法解析的隐藏成员的引用.这没问题,只要那些不在您的代码中的 SDK 类中,它仍然会编译.

Update: To clarify in your IDE when you dig into your SDK classes you might see references to hidden members which you cannot resolve. This is OK and it will still compile as long as those are in the SDK classes not in your code.

如果你想使用那些隐藏的类/方法/字段,你有两个主要选项:

If you want to use those hidden classes/methods/fields you have 2 main options:

1) 获取完整版的 android-framework.jar 并能够编译.然而,这有一个缺点,即编译后的代码可能不会在其他 Android 版本中运行,因为类或方法甚至可能不存在.并且例如 BasicTagTechnology 实际上是包私有的,因此无论如何您都无法访问它

1) fetch a full version of android-framework.jar and be able to compile. this however has a drawback that the compiled code will probably not run in other Android versions as the Class or the method might not be even there. and also BasicTagTechnology for example is actually package private so you cannot access it like that anyway

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});

这是一个更好的选择,因为它更灵活,您可以检查类/方法是否存在以初始化/调用它们,捕获异常等.

this is a better option in the sense that it is more flexible and you can check if the class/method exists to init/call them, catch exception etc.

这篇关于当 SDK 中缺少导入的类时,Android 项目如何编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆