The role of Android targetSdkVersion

Both compileSdkVersion and minSdkVersion are very easy to understand. The former represents the compiled SDK version, and the latter represents the minimum SDK version that the application is compatible with. But for targetSdkVersion, it is actually difficult to parse it clearly in one sentence. The article officially released by Google uses the word "universal" -  interesting  to describe it.

This is what Google's official article says:

targetSdkVersion is the main way Android provides forward compatibility

targetSdkVersion is the main means for the Android system to provide forward compatibility. What does it mean? With the upgrade of the Android system, the behavior of a system's API or module may change, but in order to ensure that the behavior of the old APK is still compatible with the previous one. As long as the targetSdkVersion of the APK remains unchanged, even if the APK is installed on the new Android system, its behavior remains the same as on the old system, thus ensuring the forward compatibility of the system to the old application.

Here is the example of the original text. After Android 4.4 (API 19), the behavior of AlarmManager  set() and  setRepeat() these two APIs has changed. Before Android 4.4, the two APIs set the precise time, and the system can guarantee to wake up the Alarm at the time point set by the API. The Android 4.4 system implements the alignment wake-up of AlarmManager for power saving reasons. The wake-up time set by these two APIs is treated as inaccurate time by the system. The system can only guarantee wake-up at a certain time after the time point you set.

At this time, although the API has not changed, the behavior of the API has actually changed. If this API is used in the old APK, and the behavior in the application is very dependent on the AlarmManager to wake up at the precise time, such as the alarm clock application. Problems can arise if the Android system is not guaranteed to be compatible and the old APK is installed on the new system.

How does the Android system guarantee this compatibility? At this time targetSdkVersion comes into play. When the APK calls the system AlarmManager  set() or  setRepeat() the system, the system will first check the targetSdkVersion information of the called APK. If it is less than 19, it will still follow the old behavior, that is, accurately set the wake-up time, otherwise, execute the new behavior.

Let's take a look at part of the source code for AlarmManger on Android 4.4:

private final boolean mAlwaysExact;  
AlarmManager(IAlarmManager service, Context ctx) {  
    mService = service;

    final int sdkVersion = ctx.getApplicationInfo().targetSdkVersion;
    mAlwaysExact = (sdkVersion < Build.VERSION_CODES.KITKAT);
}

Seeing this, the first choice is to obtain the targetSdkVersion of the application, and determine whether it is less than Build.VERSION_CODES.KITKAT (ie API Level 19) to set a  mAlwaysExact variable to indicate whether to use the precise time mode.

public static final long WINDOW_EXACT = 0;  
public static final long WINDOW_HEURISTIC = -1;

private long legacyExactLength() {  
    return (mAlwaysExact ? WINDOW_EXACT : WINDOW_HEURISTIC);
}

public void set(int type, long triggerAtMillis, PendingIntent operation) {  
    setImpl(type, triggerAtMillis, legacyExactLength(), 0, operation, null);
}

It can be seen here that it directly affects the set() method to  setImpl() pass in different parameters, thus affecting the execution behavior of set(). The specific implementation is  AlarmManagerService.javahere and will not be discussed further here.

Seeing this, I found that Android's targetSdkVersion is nothing special, and the system uses it very directly, even very "rough". Just use the following API to get the targetSdkVersion to determine which behavior to perform:

getApplicationInfo().targetSdkVersion;  

Therefore, we can guess that if the Android system is upgraded, when the compatible behavior changes, the old and new logics are generally saved in the original, and the  if-else method is used to determine which logic to execute. Sure enough, searching in the source code, we will find a lot  getApplicationInfo().targetSdkVersion < Buid.XXXX of code like this, which is relatively small compared to the vast amount of Android source code. In fact, in principle, the less modifications that will cause compatibility problems, the better, so every time a new Android version is released, the Android developer website will list what changes have been made. Here , developers need to pay special attention .

Finally, we can also understand the meaning of the sentence in the original text, understand why the targetSdkVersion behavior of the modified APK will change, and understand why modifying the targetSdkVersion requires a complete test.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325650505&siteId=291194637