【问题标题】:Is this considered reflection and to what degree?这被认为是反思吗?在什么程度上?
【发布时间】:2010-01-07 15:02:34
【问题描述】:

我有一个 Android 应用程序 (java),在使用 android.provider.Contacts 类中的以下代码使用 Android 1.6 SDK 编译时运行良好:

Uri baseUri = Contacts.Phones.CONTENT_FILTER_URL;

当 2.0 SDK 出来时,android.provider.Contacts 类被贬低并被 android.provider.ContactsContract 取代。为了让一个程序同时在 1.6 和 2.0 上运行,我在 1.6 下编译了以下更改:

Uri baseUri = Contacts.Phones.CONTENT_FILTER_URL;
…
try {
    Class<?> c = Class.forName("android.provider.ContactsContract$PhoneLookup");
    baseUri = (Uri) c.getField("CONTENT_FILTER_URI").get(baseUri);
} 
    catch (Exception e) {           
}

因为我是在 1.6 下编译的,所以我无法导入 android.provider.ContactsContract,因为它是一个只有 2.0 知道的类。这被认为是反思吗?程度如何?

已添加评论: 在阅读了“Java 编程语言”的“反射”一章(我应该先完成)之后,我现在基本了解了反射可以做什么,但定义很简洁反思来之不易。您的回答有助于澄清是什么引发了我的问题 - 一旦一个类被反射,并且使用反射创建了一个类的实例,您就可以与该实例进行交互,就好像该类是新的一样。

这是我对一个远非完美的简明定义的微不足道的尝试,我相信我需要在了解更多信息时进行修改:

反射是使用包含在 java.lang.reflect 或 Class 或 Package 类中的类对象的间接、动态查询、操作或调用,最初需要使用完全限定的字符串名称访问类。

【问题讨论】:

  • 请注意,尽管 URI 在 2.0 中已弃用,但该功能仍应在框架中存在一段时间(尽管有时 Android 对“弃用”一词有自己的解释)。
  • 你说得对,它仍然存在,只是2.0下的功能不起作用。不检索请求的联系人。我不记得它是否每次都返回没有联系人或“我的联系人卡片”联系人。
  • 代替上面的代码,并且依靠 ClassNotFound 异常,您可以通过环境属性主动检查您的代码正在运行的 Android 版本,然后切换调用返回的子函数BaseURI
  • 我试过了,但我必须在 1.6 下编译才能让一个应用程序同时在 1.6 和 2.0 上运行,因此在 2.0 上运行时 android.provider.ContactsContract 类不能直接使用(因为它是编译的在 1.6 中)。这就是我必须使用反射的原因。

标签: java android reflection


【解决方案1】:

我相信这就是Java reflection (more on Android reflection for multiple-version compatibility) 的定义。我不确定您所说的“程度”是什么意思;就是这样。

【讨论】:

  • 我的意思是在多大程度上是反思的全部? JasperE 说我的例子只是一种形式,它暗示反射不仅仅是“动态地询问方法的可用性”。
  • 嗯,如果需要,可以使用反射做更多的事情,例如创建对象或调用方法。您也可以使用反射来发现 Class 有哪些成员变量和类方法。
  • 您提供的“Java 反射”链接是我用来更改程序的。我只是很难从中提取一个简明的反射定义。
【解决方案2】:

动态询问方法的可用性是一种反射形式,是的。

【讨论】:

  • 所以底线是,无论何时您使用其完全限定名称访问对象都是反射,但还有其他形式的反射?
  • 没有。反射是从字符串或其他值类型访问类型对象。它是,如果您可以在字符串变量中保存类或方法的名称并获取它。这是反射,因为编译器不知道/检查该变量的值。
  • 嗯,您也可以使用反射来调用方法或创建对象。这一切都在反射的保护伞下,你所拥有的只是它的一个方面。
【解决方案3】:

这是反射。

如果CONTENT_FILTER_URI 是最终静态字段,那么您应该使用get(null) 而不是get(baseUri),因为您没有调用对象。

编辑

我对你的代码有点困惑。据我了解您的 sn-p,首先您将 Contacts.Phones.CONTENT_FILTER_URL 分配给 URL baseUri,然后在 PhoneLookup 类上反映 CONTENT_FILTER_URI 字段并从存储在 baseUri 中的 URL 实例中读取该字段值 -只是为了再次将值分配给baseUri!?错字还是有改进的余地?

【讨论】:

  • 我理解的方式是程序在1.6下运行时需要初始赋值,在2.0下运行时需要反射赋值。由于在 2.0 下会引发异常,因此在 1.6 下运行时会出现初始分配。
  • Type - 在 1.6 而不是 2.0 下抛出异常,因为 android.provider.ContactsContract 类在 1.6 下不存在。
  • Type - above = 第一条评论中的错字。
【解决方案4】:

这是一篇关于策略、反射和其他更复杂事物的非常好的文章,用于在保持与旧平台兼容的同时使用新 API:

http://android-developers.blogspot.com/2009/04/backward-compatibility-for-android.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-11
    • 1970-01-01
    • 2019-08-04
    • 2015-06-23
    • 2017-05-26
    • 2012-09-27
    • 2011-09-22
    • 1970-01-01
    相关资源
    最近更新 更多