targetSdkVersionでUIが切り替わる理由

build.gradleで指定するtargetSdkが変わるとテーマが切り替わったり、バーチャルメニューキーが表示されたりします。
Android 4.4端末で5.1のAPIレベルを指定すると以下のように今風のUIが表示されています


![image](https://qiita-image-store.s3.amazonaws.com/0/27388/7c345269-0600-9356-6143-6d38eafb9ff4.png)


しかし、Android 4.4端末で2.2のAPIレベルを指定すると以下のようにバーチャルのメニューキーが表示され、また古いUIが表示されます。また上はActionBarではなく、細いバーが表示されています。

![image](https://qiita-image-store.s3.amazonaws.com/0/27388/090427f0-ba45-7fd4-0c45-3c335efdcf8b.png)

そこで、仕組みがわからなくてもやもやしていました。

<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr">targetSdkVersionの仕組みがわからなくてもやもや、、&#10;いったいどんな仕組みでメニューボタンが現れたり消えたり、テーマが古いのになったりするのか、、</p>&mdash; takahirom (@new_runnable) <a href="https://twitter.com/new_runnable/status/631445714489315328">2015, 8月 12</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>


targetSdkVersionによって切り替える仕組みなどがあるわけではなく、
**targetSdkVersionは普通にAndroidの中のプログラムで利用するためのもの**のようです。。


ちょっと探してみたのは以下になります(違う場所を見ているなどがありましたらコメントお願いします。)

# メニューキーの切り替わるのはなぜ？
https://github.com/android/platform_frameworks_base/blob/3f453164ec884d26a556477027b430cb22a9b7e3/policy/src/com/android/internal/policy/impl/PhoneWindow.java#L3461

```java
        final Context context = getContext();
        final int targetSdk = context.getApplicationInfo().targetSdkVersion;
        final boolean targetPreHoneycomb = targetSdk < android.os.Build.VERSION_CODES.HONEYCOMB;
        if (targetPreHoneycomb || (targetPreIcs && targetHcNeedsOptions && noActionBar)) {
            setNeedsMenuKey(WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE);
        } else {
            setNeedsMenuKey(WindowManager.LayoutParams.NEEDS_MENU_SET_FALSE);
        }
```


# テーマが変わるのはなぜ？
https://github.com/android/platform_frameworks_base/blob/3f453164ec884d26a556477027b430cb22a9b7e3/core/java/android/view/ContextThemeWrapper.java#L99

```java
   @Override public Resources.Theme getTheme() {
        if (mTheme != null) {
            return mTheme;
        }

        mThemeResource = Resources.selectDefaultTheme(mThemeResource,
                getApplicationInfo().targetSdkVersion);
        initializeTheme();

        return mTheme;
    }
```

# ActionBarの高さが違うのはなぜ？
https://github.com/android/platform_frameworks_base/blob/3f453164ec884d26a556477027b430cb22a9b7e3/core/java/com/android/internal/view/ActionBarPolicy.java#L55

```java
    public boolean hasEmbeddedTabs() {
        final int targetSdk = mContext.getApplicationInfo().targetSdkVersion;
        if (targetSdk >= Build.VERSION_CODES.JELLY_BEAN) {
            return mContext.getResources().getBoolean(R.bool.action_bar_embed_tabs);
        }

        // The embedded tabs policy changed in Jellybean; give older apps the old policy
        // so they get what they expect.
        return mContext.getResources().getBoolean(R.bool.action_bar_embed_tabs_pre_jb);
    }

    public int getTabContainerHeight() {
        TypedArray a = mContext.obtainStyledAttributes(null, R.styleable.ActionBar,
                com.android.internal.R.attr.actionBarStyle, 0);
        int height = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
        Resources r = mContext.getResources();
        if (!hasEmbeddedTabs()) {
            // Stacked tabs; limit the height
            height = Math.min(height,
                    r.getDimensionPixelSize(R.dimen.action_bar_stacked_max_height));
        }
        a.recycle();
        return height;
    }
```