新的@SystemApi注解是什么意思?与@hide有什么区别?

21

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
 */
2个回答

30

@SystemApi@PrivateApi@hide

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

有关@hide javadoc注释的更多信息,请参见此帖子给出了一个很好的答案。

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

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

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

WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);

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

P.S.

WifiManager Java 代码中,setWifiApEnabledgetPrivilegedConfiguredNetworksAPI被定义为:

/**
 * 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;
    }
}

1
感谢您的解释!在我的测试中,大多数带有@SystemApi@hide注释(以前只有@hide注释)的API仍然可以通过反射访问。在您的情况下,“InvocationTargetException”的详细信息是什么? - Oasis Feng
我在我的Android 5.0上的Nexus 5上进行了实验。@oasis-feng 我猜@SystemApi的行为与版本有关? - Moony Chou
我也在安卓5.0.2的Nexus 5上进行了测试。可能因为API版本不同而有所不同。你能把你的InvocationTargetException详细信息粘贴过来吗? - Oasis Feng

7

使用@SystemApi注释的方法是@hide注释方法的子集。 这显然是内部团队(可能还包括合作伙伴)的指示,表明这些方法是实际的API,但不适用于公共开发人员。

因此,@SystemApi方法将比@hide方法更稳定,后者可能会在未来任何时候进行更改,而无需考虑任何兼容性问题,任何OEM都可以随意更改它们。

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


4
有没有办法调用带有@SystemApi注释的函数? - Gary Chen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接