【问题标题】:What's the meaning of new @SystemApi annotation, any difference from @hide?新的@SystemApi 注解是什么意思,和@hide 有什么区别?
【发布时间】:2015-01-01 09:02:33
【问题描述】:

Android 最近在其 SDK 源代码中引入了@SystemApi。似乎与之前的 @hide 注释效果相同,因为它们也被从 SDK jar 类中剥离。

应用程序是否有可能以不同于旧的@hide API 的方式调用它们。

/**
 * Indicates an API is exposed for use by bundled system applications.
 * <p>
 * These APIs are not guaranteed to remain consistent release-to-release,
 * and are not for use by apps linking against the Android SDK.
 * </p><p>
 * This annotation should only appear on API that is already marked <pre>@hide</pre>.
 * </p>
 *
 * @hide
 */

【问题讨论】:

    标签: android annotations


    【解决方案1】:

    @SystemApi@PrivateApi@hide

    根据this commit@SystemApi是旧@PrivateApi的重命名。标记为@hide 的API 不一定是@SystemApi,但@SystemApi 需要@hide

    更多关于@hidejavadoc注解的信息,this post给出了很好的答案。

    根据我自己的实验,一个(非系统应用程序)仍然可以使用 Java 反射访问@hide API 和字段,例如(来自this post):

    WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    
    WifiConfiguration config = new WifiConfiguration();
    config.SSID = "AccessPointSSID";
    
    Method method = manager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
    method.invoke(manager, config, true);
    

    但是试图访问@SystemApi事物使用Java反射是不可能的(以下代码将触发invocationTargetException):

    WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    
    Method method = manager.getClass().getMethod("getPrivilegedConfiguredNetworks");
    List<WifiConfiguration> configs = (List<WifiConfiguration>)method.invoke(manager);
    

    附言

    WifiManager java code 中,setWifiApEnabledgetPrivilegedConfiguredNetworks API 定义为:

    /**
     * Start AccessPoint mode with the specified
     * configuration. If the radio is already running in
     * AP mode, update the new configuration
     * Note that starting in access point mode disables station
     * mode operation
     * @param wifiConfig SSID, security and channel details as
     *        part of WifiConfiguration
     * @return {@code true} if the operation succeeds, {@code false} otherwise
     *
     * @hide Dont open up yet
     */
    public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
        try {
            mService.setWifiApEnabled(wifiConfig, enabled);
            return true;
        } catch (RemoteException e) {
            return false;
        }
    }
    

    /** @hide */
    @SystemApi
    public List<WifiConfiguration> getPrivilegedConfiguredNetworks() {
        try {
            return mService.getPrivilegedConfiguredNetworks();
        } catch (RemoteException e) {
            return null;
        }
    }
    

    【讨论】:

    • 感谢您的解释!在我的测试中,大多数带有@SystemApi@hide 注释的API(以前只用@hide 注释)仍然可以通过反射访问。在你的情况下InvocationTargetException的详细信息是什么?
    • 我在装有 Android 5.0 的 Nexus 5 上进行了实验。 @oasis-feng 我猜@SystemApi 的行为与版本有关?
    • 我还在 Nexus 5 和 Android 5.0.2 上进行了测试。也许它与 API 不同。您可以粘贴 InvocationTargetException 的详细消息吗?
    【解决方案2】:

    带有@SystemApi 注释的方法是带有@hide 的方法的子集。 这显然是内部团队(可能也是合作伙伴)的一个指标,这些方法是实际的 API,尽管不是针对公共开发人员。

    因此,@SystemApi 方法将比 @hide 方法更稳定,将来可以随时更改,无需任何兼容性考虑,并且任何 OEM 都可以随意更改它们。

    如果您尝试通过反射调用内部 API,请始终优先使用 @SystemApi 方法以实现更好的未来兼容性。

    【讨论】:

    • 有没有办法调用带有@SystemApi注解的函数?
    猜你喜欢
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    • 2019-04-07
    • 2019-04-11
    • 2016-02-17
    • 1970-01-01
    • 2014-08-14
    • 1970-01-01
    相关资源
    最近更新 更多