수색…


비고

참조 : https://guides.codepath.com/android/Handling-Configuration-Changes#references

활동 상태 저장 및 복원

활동이 중지되기 시작할 때 시스템은 onSaveInstanceState() 호출하여 활동이 키 - 값 쌍의 콜렉션으로 상태 정보를 저장할 수있게합니다. 이 메소드의 기본 구현은 EditText 위젯의 텍스트 또는 ListView 의 스크롤 위치와 같은 활동의 뷰 계층 구조 상태에 대한 정보를 자동으로 저장합니다.

활동에 대한 추가 상태 정보를 저장하려면 onSaveInstanceState() 구현하고 키 - 값 쌍을 Bundle 객체에 추가해야합니다. 예 :

public class MainActivity extends Activity {
    static final String SOME_VALUE = "int_value";
    static final String SOME_OTHER_VALUE = "string_value";

    @Override
    protected void onSaveInstanceState(Bundle savedInstanceState) {
        // Save custom values into the bundle
        savedInstanceState.putInt(SOME_VALUE, someIntValue);
        savedInstanceState.putString(SOME_OTHER_VALUE, someStringValue);
        // Always call the superclass so it can save the view hierarchy state
        super.onSaveInstanceState(savedInstanceState);
    }
}

Activity가 소멸되기 전에 시스템은 해당 메소드를 호출합니다. 그런 다음 시스템은 onRestoreInstanceState 를 호출하여 번들에서 상태를 복원 할 수 있습니다.

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can restore the view hierarchy
    super.onRestoreInstanceState(savedInstanceState);
    // Restore state members from saved instance
    someIntValue = savedInstanceState.getInt(SOME_VALUE);
    someStringValue = savedInstanceState.getString(SOME_OTHER_VALUE);
}

인스턴스 상태는 표준 Activity # onCreate 메소드에서도 복원 할 수 있지만 onRestoreInstanceState 에서 수행하면 모든 초기화가 완료되고 서브 클래스가 기본 구현을 사용할지 여부를 결정할 수 있으므로 편리합니다. 자세한 내용은이 stackoverflow 게시물 을 참조하십시오.

onSaveInstanceStateonRestoreInstanceState 는 함께 호출 할 수 없습니다. 안드로이드는 활동이 파괴 될 가능성이있을 때 onSaveInstanceState() 호출합니다. 그러나 onSaveInstanceState 가 호출되었지만 활동이 삭제되지 않고 onRestoreInstanceState 가 호출되지 않는 경우가 있습니다.

조각 상태 저장 및 복원

조각에는 상태를 저장해야 할 때 호출되는 onSaveInstanceState() 메서드도 있습니다.

public class MySimpleFragment extends Fragment {
    private int someStateValue;
    private final String SOME_VALUE_KEY = "someValueToSave";
   
    // Fires when a configuration change occurs and fragment needs to save state
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        outState.putInt(SOME_VALUE_KEY, someStateValue);
        super.onSaveInstanceState(outState);
    }
}

그런 다음 onCreateView 에서 저장된 상태에서 데이터를 가져올 수 있습니다.

public class MySimpleFragment extends Fragment {
   // ...

   // Inflate the view for the fragment based on layout XML
   @Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.my_simple_fragment, container, false);
        if (savedInstanceState != null) {
            someStateValue = savedInstanceState.getInt(SOME_VALUE_KEY);
            // Do something with value if needed
        }
        return view;
   }
}

프래그먼트 상태를 제대로 저장하려면 구성 변경시 프래그먼트를 불필요하게 다시 만들지 않아야합니다. 이는 이미 존재하는 조각이 이미 존재할 때 다시 초기화하지 않도록주의하는 것입니다. 액티비티에서 초기화되는 모든 프래그먼트는 구성 변경 후 태그별로 조회해야합니다.

public class ParentActivity extends AppCompatActivity {
    private MySimpleFragment fragmentSimple;
    private final String SIMPLE_FRAGMENT_TAG = "myfragmenttag";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if (savedInstanceState != null) { // saved instance state, fragment may exist
           // look up the instance that already exists by tag
           fragmentSimple = (MySimpleFragment)  
              getSupportFragmentManager().findFragmentByTag(SIMPLE_FRAGMENT_TAG);
        } else if (fragmentSimple == null) { 
           // only create fragment if they haven't been instantiated already
           fragmentSimple = new MySimpleFragment();
        }
    }
}

따라서 트랜잭션 내에서 조각을 활동에 넣을 때마다 조회 용 태그를 포함해야합니다.

public class ParentActivity extends AppCompatActivity {
    private MySimpleFragment fragmentSimple;
    private final String SIMPLE_FRAGMENT_TAG = "myfragmenttag";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // ... fragment lookup or instantation from above...
        // Always add a tag to a fragment being inserted into container
        if (!fragmentSimple.isInLayout()) {
            getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.container, fragmentSimple, SIMPLE_FRAGMENT_TAG)
                .commit();
        }
    }
}

이 간단한 패턴을 사용하여 프래그먼트를 올바르게 재사용하고 구성 변경시 상태를 복원 할 수 있습니다.

조각 유지하기

많은 경우, 단순히 조각을 사용하여 활동을 다시 만들 때 문제를 피할 수 있습니다. 뷰와 상태가 조각 안에 있으면 활동을 다시 만들 때 조각을 유지할 수 있습니다.

public class RetainedFragment extends Fragment {
    // data object we want to retain
    private MyDataObject data;

    // this method is only called once for this fragment
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // retain this fragment when activity is re-initialized
        setRetainInstance(true);
    }

    public void setData(MyDataObject data) {
        this.data = data;
    }

    public MyDataObject getData() {
        return data;
    }
}

이 접근법은 활동 라이프 사이클 동안 조각이 파손되지 않도록합니다. 대신 Fragment Manager에 유지됩니다. 자세한 내용은 Android 공식 문서를 참조 하십시오 .

이제 조각을 만들기 전에 조각이 태그에 의해 이미 존재하는지 확인할 수 있습니다. 단편 조각은 구성 변경 사항 전체에서 상태를 유지합니다. 자세한 내용은 런타임 변경 처리 설명서를 참조하십시오 .

잠금 화면 방향

Android 애플리케이션의 화면 (액티비티) 화면 방향 변경을 잠 그려면 AndroidManifest.xml 에서 <activity>android:screenOrientation 속성을 설정하기 android:screenOrientation 됩니다.

<activity
    android:name="com.techblogon.screenorientationexample.MainActivity"
    android:screenOrientation="portrait"
    android:label="@string/app_name" >
    <!-- ... -->
</activity>

이제 그 활동은 항상 " 인물 "모드로 표시되어야합니다.

수동으로 구성 변경 관리

특정 구성이 변경되는 동안 응용 프로그램에서 자원을 업데이트 할 필요가 없으며 활동을 다시 시작하지 않아야하는 성능 한계가있는 경우 활동이 구성 변경 자체를 처리하도록 선언 할 수 있습니다. 활동.

그러나이 기술은 구성 변경으로 인한 재시작을 피해야하며 대부분의 응용 프로그램에는 권장되지 않는 최후의 수단으로 간주되어야합니다. 이 접근 방식을 사용하려면 AndroidManifest.xml 내 활동에 android:configChanges 노드를 추가해야합니다.

<activity android:name=".MyActivity"
          android:configChanges="orientation|screenSize|keyboardHidden"
          android:label="@string/app_name">

이제 이러한 구성 중 하나가 변경되면 활동이 다시 시작되지 않고 대신 onConfigurationChanged() 대한 호출을받습니다.

// Within the activity which receives these changes
// Checks the current device orientation, and toasts accordingly
@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
}

변경 문서 처리를 참조하십시오. 활동에서 처리 할 수있는 구성 변경 사항에 대한 자세한 내용은 android : configChanges 설명서 및 Configuration 클래스를 참조하십시오.

AsyncTask 처리

문제:

  • AsyncTask 가 시작된 후 화면 회전이 있으면 소유하는 활동이 삭제되고 다시 작성됩니다.
  • AsyncTask 가 끝나면 더 이상 유효하지 않은 UI를 업데이트하려고합니다.

해결책:

로더를 사용하면 활동 파괴 / 재현을 쉽게 극복 할 수 있습니다.

예:

주요 활동:

public class MainActivity extends AppCompatActivity 
        implements LoaderManager.LoaderCallbacks<Bitmap> {

    //Unique id for the loader
    private static final int MY_LOADER = 0; 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        LoaderManager loaderManager = getSupportLoaderManager();

        if(loaderManager.getLoader(MY_LOADER) == null) {
            loaderManager.initLoader(MY_LOADER, null, this).forceLoad();
        }
    }

    @Override
    public Loader<Bitmap> onCreateLoader(int id, Bundle args) {
        //Create a new instance of your Loader<Bitmap>
        MyLoader loader = new MyLoader(MainActivity.this);
        return loader;
    }

    @Override
    public void onLoadFinished(Loader<Bitmap> loader, Bitmap data) {
        // do something in the parent activity/service
        // i.e. display the downloaded image
        Log.d("MyAsyncTask", "Received result: ");
    }

    @Override
    public void onLoaderReset(Loader<Bitmap> loader) {

    }
}

AsyncTaskLoader :

public class MyLoader extends AsyncTaskLoader<Bitmap> {
    private WeakReference<Activity> motherActivity;

    public MyLoader(Activity activity) {
        super(activity);
        //We don't use this, but if you want you can use it, but remember, WeakReference
        motherActivity = new WeakReference<>(activity);
    }

    @Override
    public Bitmap loadInBackground() {
        // Do work. I.e download an image from internet to be displayed in gui.
        // i.e. return the downloaded gui
        return result;
    }
}

노트 :

v4 호환성 라이브러리를 사용하거나 사용하지 않는 것이 중요하지만, 컴파일 오류로 이어질 수 있으므로 하나의 일부와 다른 일부를 사용하지 마십시오. 확인을 위해 android.support.v4.contentandroid.content 에 대한 가져 오기를 볼 수 있습니다 (두 가지 모두 없어야 함).

프로그래밍 방식으로 화면 회전 잠금

개발하는 동안 코드의 특정 부분에서 장치 화면을 잠 그거나 잠금을 해제하는 것이 매우 유용 할 수 있습니다 .

예를 들어 정보가있는 대화 상자를 표시하는 동안 개발자는 대화 상자가 닫히지 않도록 화면의 회전을 잠그고 대화 상자를 닫을 때 현재 활동을 다시 작성하여 다시 열지 못하게 할 있습니다.

다음을 수행하여 매니페스트에서 로테이션 잠금을 얻을 수는 있습니다.

<activity
    android:name=".TheActivity"
    android:screenOrientation="portrait"
    android:label="@string/app_name" >
</activity>

다음을 수행하여 프로그래밍 방식으로도이를 수행 할 수 있습니다.

public void lockDeviceRotation(boolean value) {
    if (value) {
        int currentOrientation = getResources().getConfiguration().orientation;
        if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
        }
    } else {
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_USER);
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
        }
    }
}

다음을 호출하여 장치 회전을 잠 그거나 잠금 해제합니다.

lockDeviceRotation(true)

lockDeviceRotation(false) 


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow