1. 程式人生 > >防止Activity被重新建立

防止Activity被重新建立

Activity在系統配置發生改變之後會重新建立,我們常見的是在手機旋轉螢幕時activity就被重新建立了。那麼怎麼樣才能不被建立呢?我們先來看一下系統的那些內容被改變後Activity會被重新建立。
系統的配置在Configuration類中,我們來檢視Configuration類中的成員,看看他們分別代表的意思。

  1. mcc: SIM卡唯一標示IMSI(國際移動使用者識別碼)中的國家程式碼,由三位數字組成,中國為460。此項標示mcc程式碼發生了改變
  2. mnc: SIM卡的唯一標示IMSI(國際移動使用者識別碼)中的運營商程式碼,由2位數字組成,中國移動TD系統為00,中國聯通為01,此項標示mnc發生改變
  3. locale:裝置的本地位置發生了改變,一般指切換了系統語言。
  4. touchscreen:觸屏發生了改變
  5. keyboard:鍵盤型別發生了改變,比如使用了外接鍵盤
  6. keyboardHidden:鍵盤的可訪問性發生了改變,比如使用者調出了鍵盤
  7. navigation:系統導航發生了改變,比如採用了軌跡導航,這個有點費解,很難發生,可以忽略它。
  8. srceenLayout:屏幕布局發生了改變,很可能是激活了另外一個顯示裝置
  9. frontScale:系統字型縮放比例發生了變化,比如使用者選擇了一個新字號
  10. uiMode:使用者介面模式發生了改變,比如是否開啟了夜間模式(API8新加)
  11. orientation:螢幕方向發生了改變,這個是最常用的,比如旋轉了手機螢幕
  12. sreenSize:當螢幕尺寸資訊發生改變,當選裝裝置時,螢幕尺寸會發生改變,這個選項比較特殊,它和編譯選項有關,當編譯選項中的minSdkVersion 和 targetSdkVersion均低於13時,此選項不會到時Activity重啟,負責Activity將重啟(api13)新增
  13. smallScreenSize:裝置的物理尺寸發生改變,這個專案和螢幕的方向沒關係,僅僅表示在實習的物理螢幕的尺寸發生改變的時候,比如使用者切換到了外部的顯示裝置,這個選項和srceenSize一樣,當編譯選項中中的minSdkVersion和targetSdkVersion均低於13時,此選項不會導致Activity重啟,負責將導致Activity重啟(API13新新增)
  14. layoutDirection:當佈局發生變化,這個屬性用的比較少,正常情況下無須修改佈局的layoutDirection屬性(API17新新增)

    上面列出的專案很多,其實我們常用的就 locale、orientation 和 keyboardHidden這三項。

那麼我們來看一下怎麼讓這些配置改變之後,Activity不重建呢?其實很簡單。
比如我們不想讓 螢幕方向發生改變時Activity重建,那麼只需在AndroidManfest.xml中對應的Activity標籤中新增一句 android:configChanges=”orientation”

    <activity android:name=".MainActivity"
            android:configChanges="orientation"  //新增這句
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

那麼當螢幕發生改變時,Activity不會被重建。但會回撥Activity中的onConfigurationChanged方法。我在實際應用中發現:只添android:configChanges=”orientation” 不能阻止Activity重建,原因在於:在螢幕旋轉是srceenSize 也發生了改變。所有最後決定這樣寫:android:configChanges=”orientation|screenSize”
那麼我們來看一下我的程式碼,以及執行結果
MainActivity.java

package com.simple.myapplication;

import android.content.Intent;
import android.content.res.Configuration;
import android.os.PersistableBundle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this,SecondActivity.class));

            }
        });

        Log.i(TAG, "onCreate: ");
    }

    @Override
    public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
        super.onCreate(savedInstanceState, persistentState);

    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.i(TAG, "onStart: ");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i(TAG, "onRestart: ");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG, "onResume: ");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i(TAG, "onStop: ");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i(TAG, "onPause: ");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy: ");
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        outState.putInt("key",1);
        super.onSaveInstanceState(outState);
        Log.i(TAG, "onSaveInstanceState: ");
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        int i  = savedInstanceState.getInt("key");
        super.onRestoreInstanceState(savedInstanceState);
        Log.i(TAG, "onRestoreInstanceState:");
    }


     /**
     * AndroidManifest如果新增 configChanges ="..." 使得Acivity不重建
     * 則會呼叫這個方法
     * @param newConfig
     */
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Log.i(TAG, "onConfigurationChanged: "+newConfig.orientation);
    }
}



AndroidManifest.xml

 <activity android:name=".MainActivity"
            android:configChanges="orientation|screenSize"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
執行結果:
com.simple.myapplication I/MainActivity: onConfigurationChanged: 2
com.simple.myapplication I/MainActivity: onConfigurationChanged: 1
com.simple.myapplication I/MainActivity: onConfigurationChanged: 2

注意我這裡的指定的minSdkVersion和tagetSdkVersion大於13,所以為了防止螢幕旋轉時Activity重啟,除了orientation,我們還要新增srceenSize。