What's the meaning of new @SystemApi annotation, any difference from @hide?

后端 未结 2 1219
不知归路
不知归路 2020-12-14 09:42

Android introduced @SystemApi in its SDK source code recently. Seems like same in effect as the @hide annotation before, since they also got stripped from SDK jar classes.

相关标签:
2条回答
  • 2020-12-14 10:11

    @SystemApi, @PrivateApi and @hide

    According to this commit, @SystemApi is a rename of the old @PrivateApi. APIs marked @hide are not necessarily @SystemApi, but @SystemApi requires @hide.

    For more information about @hide javadoc annotation, this post gives a good answer.

    Based on my own experiments, one (non-system application) can still access @hide APIs and fields using Java reflection like (from 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);
    

    But trying to access @SystemApi things using Java reflection is impossible (following code will trigger invocationTargetException):

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

    P.S.

    In the WifiManager java code, the setWifiApEnabled and getPrivilegedConfiguredNetworks APIs are defined as:

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

    and

    /** @hide */
    @SystemApi
    public List<WifiConfiguration> getPrivilegedConfiguredNetworks() {
        try {
            return mService.getPrivilegedConfiguredNetworks();
        } catch (RemoteException e) {
            return null;
        }
    }
    
    0 讨论(0)
  • 2020-12-14 10:17

    Methods annotated with @SystemApi are a subset of ones with @hide. It's apparently an indicator for internal teams (perhaps also partners) that these methods are actual APIs, although not for public developers.

    As a result, @SystemApi methods will be more stable than @hide ones, which could be changed at any time in the future without any compatibility consideration, and also any OEM is allowed to change them at their own will.

    If you are trying to invoke internal APIs via reflection, always prefer @SystemApi methods for better future compatibility.

    0 讨论(0)
提交回复
热议问题