Какой смысл новой аннотации @SystemApi, любая разница от @hide?

Android недавно представил @SystemApi в своем исходном коде SDK. Похоже на то же, что и аннотация @hide, так как они также были удалены из классов jar SDK.

Есть ли вероятность, что приложение может называть их способами, отличными от старых API @hide.

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

Ответ 1

Методы, аннотированные с @SystemApi, являются подмножеством из них с @hide. По-видимому, это показатель для внутренних команд (возможно, также партнеров), что эти методы являются фактическими API, хотя и не для публичных разработчиков.

В результате методы @SystemApi будут более стабильными, чем @hide, которые могут быть изменены в любое время в будущем без какого-либо рассмотрения совместимости, а также любой OEM-сервер может изменить их по своему усмотрению.

Если вы пытаетесь вызвать внутренние API через отражение, всегда предпочитайте методы @SystemApi для лучшей совместимости в будущем.

Ответ 2

@SystemApi, @PrivateApi и @hide

Согласно этой фиксации, @SystemApi является переименованием старого @PrivateApi. API, отмеченные @hide, не обязательно @SystemApi, но @SystemApi требует @hide.

Для получения дополнительной информации о аннотации @hide javadoc этот пост дает хороший ответ.

Основываясь на моих собственных экспериментах, одно (несистемное приложение) может по-прежнему обращаться @hide API-интерфейсам и полям @hide используя отражение Java, подобное (из этого сообщения):

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

PS

В WifiManager коде Java, то setWifiApEnabled и getPrivilegedConfiguredNetworks 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;
    }
}

Ответ 3

Я пытаюсь вызвать createCustomCaptureSession из класса cameraDevice, который является @SystemApi, но получает "ошибку нулевого получателя".

     try {
            Method method = mCameraDevice.getClass().getMethod("createCustomCaptureSession", InputConfiguration.class, List.class,int.class,CameraCaptureSession.StateCallback.class, Handler.class);
            method.invoke(null,Arrays.asList(previewSurface),140,previewOnlySessionStateCallback,mBackgroundHandler);

        } catch (Exception e)
      {
         e.getStackTrace().toString();
         Log.d("createCustom",e.getMessage());
      }