본문

[2018.09.09] 110. TargetSDK 27로 설정 시, 주의할 점

도입

이번 포스팅에서는 Android에서 target SDK를 27(Orea)로 설정 시, 주의 할 점에 대해 정리할 예정이다.

target SDK를 27로 올리며 기존 코드의 문제로 crash가 발생했고 이를 해결하는 과정을 정리할 예정이다.


문제점

targetSDK를 27로 설정 했을 때 기존에

1. translucent 설정

2. screenOrientation 설정

이 되어 있는 경우, 아래와 같이 crash(Only fullscreen opaque activities can request orientation) 발생


원인

1. targetSDK 설정이 Orea보다 높으면서 (Orea 포함 X) 해당 Activity가 고정되어 있을 때 If 진입

2. Activity가 translucent거나 floating일 경우 해당 Exception 발생

(해당 코드가 삽입된 히스토리 - https://goo.gl/LxMCh9)

8.0(Oreo) Activity.java 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@MainThread
@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
    if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
    if (getApplicationInfo().targetSdkVersion > O && mActivityInfo.isFixedOrientation()) {
        final TypedArray ta = obtainStyledAttributes(com.android.internal.R.styleable.Window);
        final boolean isTranslucentOrFloating = ActivityInfo.isTranslucentOrFloating(ta);
        ta.recycle();
        if (isTranslucentOrFloating) {
            throw new IllegalStateException(
                "Only fullscreen opaque activities can request orientation");
        }
    }
    if (mLastNonConfigurationInstances != null) {
        mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
    }
    if (mActivityInfo.parentActivityName != null) {
        if (mActionBar == null) {
            mEnableDefaultActionBarUp = true;
        } else {
            mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
        }
    }
    if (savedInstanceState != null) {
        mAutoFillResetNeeded = savedInstanceState.getBoolean(AUTOFILL_RESET_NEEDED, false);
        mLastAutofillId = savedInstanceState.getInt(LAST_AUTOFILL_ID,
            View.LAST_APP_AUTOFILL_ID);
        if (mAutoFillResetNeeded) {
            getAutofillManager().onCreate(savedInstanceState);
        }
        Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
        mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
            ? mLastNonConfigurationInstances.fragments : null);
    }
    mFragments.dispatchCreate();
    getApplication().dispatchActivityCreated(this, savedInstanceState);
    if (mVoiceInteractor != null) {
        mVoiceInteractor.attachActivity(this);
    }
    mCalled = true;
}
cs


8.1(Oreo)에서는 아래와 같이 해당 코드가 삭제된 것을 확인할 수 있다.

 8.1(Oreo) Activity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@MainThread
@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
    if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
    if (mLastNonConfigurationInstances != null) {
        mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
    }
    if (mActivityInfo.parentActivityName != null) {
        if (mActionBar == null) {
            mEnableDefaultActionBarUp = true;
        } else {
            mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
        }
    }
    if (savedInstanceState != null) {
        mAutoFillResetNeeded = savedInstanceState.getBoolean(AUTOFILL_RESET_NEEDED, false);
        mLastAutofillId = savedInstanceState.getInt(LAST_AUTOFILL_ID,
            View.LAST_APP_AUTOFILL_ID);
        if (mAutoFillResetNeeded) {
            getAutofillManager().onCreate(savedInstanceState);
        }
        Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
        mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
            ? mLastNonConfigurationInstances.fragments : null);
    }
    mFragments.dispatchCreate();
    getApplication().dispatchActivityCreated(this, savedInstanceState);
    if (mVoiceInteractor != null) {
        mVoiceInteractor.attachActivity(this);
    }
    mRestoredFromBundle = savedInstanceState != null;
    mCalled = true;
}
cs



해결책

여러 방법이 있겠지만 가장 단순한 방법은 

1. screenOrientation 설정 삭제

1
2
3
4
<activity android:name=".SecondActivity"
    android:screenOrientation="portrait"
    android:theme="@style/Theme.AppCompat.NoActionBar.Trans"
    android:configChanges="orientation|screenSize|screenLayout" />
cs


2. Theme를 v26, v27일 때 설정 나누기 

  • v26
    1
    2
    3
    4
    <style name="Theme.AppCompat.NoActionBar.Trans" parent="Theme.AppCompat.NoActionBar">
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@color/transparent</item>
    </style>
    cs
  • v27
    1
    2
    3
    4
    <style name="Theme.AppCompat.NoActionBar.Trans" parent="Theme.AppCompat.NoActionBar">
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@color/transparent</item>
    </style>
    cs


#Only fullscreen opaque activities can request orientation #targetSDK error

공유

댓글