Какой смысл новой аннотации @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());
}