防止Activity被重新建立
Activity在系統配置發生改變之後會重新建立,我們常見的是在手機旋轉螢幕時activity就被重新建立了。那麼怎麼樣才能不被建立呢?我們先來看一下系統的那些內容被改變後Activity會被重新建立。
系統的配置在Configuration類中,我們來檢視Configuration類中的成員,看看他們分別代表的意思。
- mcc: SIM卡唯一標示IMSI(國際移動使用者識別碼)中的國家程式碼,由三位數字組成,中國為460。此項標示mcc程式碼發生了改變
- mnc: SIM卡的唯一標示IMSI(國際移動使用者識別碼)中的運營商程式碼,由2位數字組成,中國移動TD系統為00,中國聯通為01,此項標示mnc發生改變
- locale:裝置的本地位置發生了改變,一般指切換了系統語言。
- touchscreen:觸屏發生了改變
- keyboard:鍵盤型別發生了改變,比如使用了外接鍵盤
- keyboardHidden:鍵盤的可訪問性發生了改變,比如使用者調出了鍵盤
- navigation:系統導航發生了改變,比如採用了軌跡導航,這個有點費解,很難發生,可以忽略它。
- srceenLayout:屏幕布局發生了改變,很可能是激活了另外一個顯示裝置
- frontScale:系統字型縮放比例發生了變化,比如使用者選擇了一個新字號
- uiMode:使用者介面模式發生了改變,比如是否開啟了夜間模式(API8新加)
- orientation:螢幕方向發生了改變,這個是最常用的,比如旋轉了手機螢幕
- sreenSize:當螢幕尺寸資訊發生改變,當選裝裝置時,螢幕尺寸會發生改變,這個選項比較特殊,它和編譯選項有關,當編譯選項中的minSdkVersion 和 targetSdkVersion均低於13時,此選項不會到時Activity重啟,負責Activity將重啟(api13)新增
- smallScreenSize:裝置的物理尺寸發生改變,這個專案和螢幕的方向沒關係,僅僅表示在實習的物理螢幕的尺寸發生改變的時候,比如使用者切換到了外部的顯示裝置,這個選項和srceenSize一樣,當編譯選項中中的minSdkVersion和targetSdkVersion均低於13時,此選項不會導致Activity重啟,負責將導致Activity重啟(API13新新增)
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。