??在Activity A切換到Activity B時(shí),有時(shí)會(huì)遇到黑屏或者白屏的閃屏問(wèn)題凿菩,經(jīng)常我們會(huì)給Activity B設(shè)置一個(gè)透明主題來(lái)解決,即通過(guò)設(shè)置屬性android:windowIsTranslucent=true或者android:windowBackground=@color/transparent。那么這兩個(gè)屬性有區(qū)別呢?下面從它們對(duì)Activity生命周期的影響來(lái)對(duì)比說(shuō)明题涨。
android:windowIsTranslucent 窗口是否設(shè)置為半透明
android:windowBackground 整個(gè)窗口的背景偎谁,包括邊框和內(nèi)部
Activity A :MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button btnTransActivity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e(Contants.TAG,"MainActivity onCreate");
setContentView(R.layout.activity_main);
initView();
initListener();
}
@Override
protected void onRestart() {
super.onRestart();
Log.e(Contants.TAG,"MainActivity onRestart");
}
@Override
protected void onStart() {
super.onStart();
Log.e(Contants.TAG,"MainActivity onStart");
}
@Override
protected void onResume() {
super.onResume();
Log.e(Contants.TAG,"MainActivity onResume");
}
@Override
protected void onPause() {
super.onPause();
Log.e(Contants.TAG,"MainActivity onPause");
}
@Override
protected void onStop() {
super.onStop();
Log.e(Contants.TAG,"MainActivity onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.e(Contants.TAG,"MainActivity onDestroy");
}
private void initView() {
btnTransActivity = findViewById(R.id.btnTransActivity);
}
private void initListener() {
btnTransActivity.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btnTransActivity:
Intent intent = new Intent(MainActivity.this,TransparentThemeActivity.class);
startActivity(intent);
break;
default:
break;
}
}
}
Activity B:TransparentThemeActivity
public class TransparentThemeActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e(Contants.TAG,"TransparentThemeActivity onCreate");
setContentView(R.layout.activity_transparent_theme);
}
@Override
protected void onRestart() {
super.onRestart();
Log.e(Contants.TAG,"TransparentThemeActivity onRestart");
}
@Override
protected void onStart() {
super.onStart();
Log.e(Contants.TAG,"TransparentThemeActivity onStart");
}
@Override
protected void onResume() {
super.onResume();
Log.e(Contants.TAG,"TransparentThemeActivity onResume");
}
@Override
protected void onPause() {
super.onPause();
Log.e(Contants.TAG,"TransparentThemeActivity onPause");
}
@Override
protected void onStop() {
super.onStop();
Log.e(Contants.TAG,"TransparentThemeActivity onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.e(Contants.TAG,"TransparentThemeActivity onDestroy");
}
}
Activity B的theme
<!--主題1-->
<style name="TransparentTheme1" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsTranslucent">true</item>
</style>
<!--主題2-->
<style name="TransparentTheme2" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@color/transparent</item>
<item name="android:windowNoTitle">true</item>
</style>
后臺(tái)可見狀態(tài):onStart
用戶可見狀態(tài):onResume
1、Activit A切換到B
(1)android:windowIsTranslucent = true
07-01 17:22:42.768 13454-13454/com.lmz.viewdemo E/activity: MainActivity onCreate
07-01 17:22:42.836 13454-13454/com.lmz.viewdemo E/activity: MainActivity onStart
07-01 17:22:42.839 13454-13454/com.lmz.viewdemo E/activity: MainActivity onResume
07-01 17:22:48.925 13454-13454/com.lmz.viewdemo E/activity: MainActivity onPause
07-01 17:22:48.953 13454-13454/com.lmz.viewdemo E/activity: TransparentThemeActivity onCreate
07-01 17:22:48.975 13454-13454/com.lmz.viewdemo E/activity: TransparentThemeActivity onStart
07-01 17:22:48.979 13454-13454/com.lmz.viewdemo E/activity: TransparentThemeActivity onResume
??從打印的log中可以發(fā)現(xiàn)Activity A(MainActivity)切換到B時(shí)纲堵,只執(zhí)行到了onPause方法巡雨,并沒(méi)有執(zhí)行onStop方法,所以在Activity B對(duì)用戶可見時(shí)席函,下面的Activity A是處于部分可見的狀態(tài)鸯隅。
(2)android:windowBackground=@color/transparent
07-01 18:33:26.480 15730-15730/com.lmz.viewdemo E/activity: MainActivity onCreate
07-01 18:33:26.542 15730-15730/com.lmz.viewdemo E/activity: MainActivity onStart
07-01 18:33:26.544 15730-15730/com.lmz.viewdemo E/activity: MainActivity onResume
07-01 18:33:43.268 15730-15730/com.lmz.viewdemo E/activity: MainActivity onPause
07-01 18:33:43.294 15730-15730/com.lmz.viewdemo E/activity: TransparentThemeActivity onCreate
07-01 18:33:43.312 15730-15730/com.lmz.viewdemo E/activity: TransparentThemeActivity onStart
07-01 18:33:43.315 15730-15730/com.lmz.viewdemo E/activity: TransparentThemeActivity onResume
07-01 18:33:43.698 15730-15730/com.lmz.viewdemo E/activity: MainActivity onStop
??activity A和B的生命周期執(zhí)行順序正常。
2向挖、在Activity B頁(yè)面蝌以,點(diǎn)擊back鍵返回到A頁(yè)面
(1)android:windowIsTranslucent = true
07-01 18:44:22.894 16995-16995/com.lmz.viewdemo E/activity: TransparentThemeActivity onPause
07-01 18:44:22.907 16995-16995/com.lmz.viewdemo E/activity: MainActivity onResume
07-01 18:44:22.935 16995-16995/com.lmz.viewdemo E/activity: TransparentThemeActivity onStop
07-01 18:44:22.936 16995-16995/com.lmz.viewdemo E/activity: TransparentThemeActivity onDestroy
??從1的activity切換操作中可知Activity A(MainActivity)并未調(diào)用onStop方法,只調(diào)用了onPause何之,所以點(diǎn)擊back鍵跟畅,Activity A要從onPause狀態(tài)到對(duì)用戶可見,只需要調(diào)用onResume方法(可上google官網(wǎng)查看activity生命周期圖)溶推。
(2)android:windowBackground=@color/transparent
07-01 18:42:34.013 15730-15730/com.lmz.viewdemo E/activity: TransparentThemeActivity onPause
07-01 18:42:34.019 15730-15730/com.lmz.viewdemo E/activity: MainActivity onRestart
07-01 18:42:34.019 15730-15730/com.lmz.viewdemo E/activity: MainActivity onStart
07-01 18:42:34.020 15730-15730/com.lmz.viewdemo E/activity: MainActivity onResume
07-01 18:42:34.329 15730-15730/com.lmz.viewdemo E/activity: TransparentThemeActivity onStop
07-01 18:42:34.329 15730-15730/com.lmz.viewdemo E/activity: TransparentThemeActivity onDestroy
??點(diǎn)擊back鍵徊件,Activity A從onStop狀態(tài)到用戶可見狀態(tài),需要調(diào)用onRestart蒜危、onStart虱痕、onResume方法,所以辐赞,點(diǎn)擊back鍵也不會(huì)影響到activity的生命周期
3部翘、停留在B頁(yè)面,將應(yīng)用從前臺(tái)切到后臺(tái)
(1)android:windowIsTranslucent = true
07-01 18:48:51.428 16995-16995/com.lmz.viewdemo E/activity: TransparentThemeActivity onPause
07-01 18:48:51.483 16995-16995/com.lmz.viewdemo E/activity: MainActivity onStop
07-01 18:48:51.486 16995-16995/com.lmz.viewdemo E/activity: TransparentThemeActivity onStop
??從日志中可以看到响委,Activity A和Activity B都完全不可見(onStop)新思。而在A切到B時(shí),A只調(diào)用了onPause方法赘风,所以切到后臺(tái)時(shí)夹囚,A到完全不可見,也調(diào)用onStop方法邀窃。
(2)android:windowBackground=@color/transparent
07-01 18:51:15.099 18093-18093/com.lmz.viewdemo E/activity: TransparentThemeActivity onPause
07-01 18:51:15.151 18093-18093/com.lmz.viewdemo E/activity: TransparentThemeActivity onStop
??在A切換到B時(shí)荸哟,A已經(jīng)完全不可見了,所以切到后臺(tái)時(shí)瞬捕,只有Activity B從可見到完全不可見鞍历,會(huì)調(diào)用onPause、onStop方法山析。
4堰燎、將應(yīng)用切回前臺(tái)
(1)android:windowIsTranslucent = true
07-01 18:49:19.897 16995-16995/com.lmz.viewdemo E/activity: MainActivity onRestart
07-01 18:49:19.901 16995-16995/com.lmz.viewdemo E/activity: MainActivity onStart
07-01 18:49:19.904 16995-16995/com.lmz.viewdemo E/activity: TransparentThemeActivity onRestart
07-01 18:49:19.906 16995-16995/com.lmz.viewdemo E/activity: TransparentThemeActivity onStart
07-01 18:49:19.907 16995-16995/com.lmz.viewdemo E/activity: TransparentThemeActivity onResume
??從日志中可以看到,Activity A和B都從不可見狀態(tài)(onStop)到可見的狀態(tài)笋轨,只有B是到用戶可見狀態(tài)(onResume)秆剪。
(2)android:windowBackground=@color/transparent
07-01 18:51:40.964 18093-18093/com.lmz.viewdemo E/activity: TransparentThemeActivity onRestart
07-01 18:51:40.964 18093-18093/com.lmz.viewdemo E/activity: TransparentThemeActivity onStart
07-01 18:51:40.965 18093-18093/com.lmz.viewdemo E/activity: TransparentThemeActivity onResume
??只有activity B從不可見狀態(tài)到用戶可見的狀態(tài)赊淑。
小結(jié):
1、android:windowBackground不影響Activity的生命周期,即啟動(dòng)設(shè)置了該屬性的Activity的生命周期不會(huì)受到影響仅讽。
2陶缺、android:windowIsTranslucent = true會(huì)影響到Activity的生命周期,比如啟動(dòng)一個(gè)設(shè)置了該屬性的Activity洁灵,若該activity對(duì)用戶可見時(shí)饱岸,啟動(dòng)它的activity(即它下層的activity)并未完全不可見(即調(diào)用到了onPause,不會(huì)調(diào)用onStop方法)徽千,具體可見上面的操作對(duì)Activity生命周期的影響苫费。
優(yōu)化:在實(shí)際開發(fā)中,發(fā)現(xiàn)對(duì)于Activity切換出現(xiàn)黑屏或者白屏處理中双抽,若使用android:windowBackground對(duì)于7.0系統(tǒng)以上的手機(jī)還是會(huì)有閃屏的現(xiàn)象百框,若使用android:windowIsTranslucent = true就不會(huì)有閃屏現(xiàn)象,但是有兩種情況需要進(jìn)行優(yōu)化:
1牍汹、需要在應(yīng)用從前臺(tái)切到后臺(tái)時(shí)铐维,執(zhí)行操作。
判斷是否切換后臺(tái)的時(shí)機(jī)就需要放到onPause中去慎菲,若是切換后臺(tái)嫁蛇,則執(zhí)行操作。
2露该、需要在應(yīng)用從后臺(tái)切到前臺(tái)時(shí)睬棚,執(zhí)行操作。
若Activity A的上一層Activity B是透明主題有决,并且當(dāng)前Activity B對(duì)用戶完全可見的闸拿,此時(shí)Activity A處于onPause狀態(tài)空盼。
(1)停留在Activity B頁(yè)面书幕,應(yīng)用從前臺(tái)切換到后臺(tái)時(shí),Activity A也會(huì)執(zhí)行onStop方法揽趾, 在onStop方法中判斷應(yīng)用是否切換到后臺(tái)台汇,是,將全局變量AppUtils.isBackGroundStart置為true篱瞎,否則置為false苟呐。
(2)應(yīng)用從后臺(tái)切回前臺(tái)時(shí),當(dāng)前只會(huì)有一個(gè)Activity會(huì)執(zhí)行onResume方法(停留在Activity B頁(yè)面時(shí)切到后臺(tái)俐筋,所以切回前臺(tái)時(shí)牵素,只有Activity B會(huì)執(zhí)行onResume), 此時(shí)可以通過(guò)全局變量isBackGroundStart判斷應(yīng)用是否是從后臺(tái)切到前臺(tái)的澄者,執(zhí)行需要在這個(gè)時(shí)機(jī)完成的操作后將isBackGroundStart置為false笆呆。
AppUtils.java
public static boolean isBackGroundStart = false;//是否從后臺(tái)開啟
/**
*
* 若Activity A的上一層Activity B是透明主題请琳,并且當(dāng)前Activity B對(duì)用戶完全可見的,此時(shí)Activity A處于onPause狀態(tài)赠幕。
* 1俄精、停留在Activity B頁(yè)面,應(yīng)用從前臺(tái)切換到后臺(tái)時(shí)榕堰,Activity A也會(huì)執(zhí)行onStop方法竖慧,
* 在onStop方法中判斷應(yīng)用是否切換到后臺(tái),是逆屡,將全局變量AppUtils.isBackGroundStart置為true圾旨,否則置為false。
* 2魏蔗、應(yīng)用從后臺(tái)切回前臺(tái)時(shí)碳胳,當(dāng)前只會(huì)有一個(gè)Activity會(huì)執(zhí)行onResume方法(停留在Activity B頁(yè)面時(shí)切到后臺(tái),所以切回前臺(tái)時(shí)沫勿,只有Activity B會(huì)執(zhí)行onResume)挨约,
* 此時(shí)可以通過(guò)全局變量isBackGroundStart判斷應(yīng)用是否是從后臺(tái)切到前臺(tái)的,執(zhí)行需要在這個(gè)時(shí)機(jī)完成的操作后將isBackGroundStart置為false产雹。
* =氩选!蔓挖!注意:這里的透明主題是指使用android:windowIsTranslucent = true設(shè)置窗口半透明
* @param context
* @return
*/
public static boolean isBackground(Context context) {
ActivityManager ActivityManager = (ActivityManager) context
.getSystemService(ACTIVITY_SERVICE);
List<android.app.ActivityManager.RunningAppProcessInfo> appProcesses = ActivityManager
.getRunningAppProcesses();
isBackGroundStart = false;
if (TextUtil.isValidate(appProcesses)) {
for (android.app.ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess != null && appProcess.processName.equals(context.getPackageName())) {
/*
BACKGROUND=400 EMPTY=500 FOREGROUND=100
GONE=1000 PERCEPTIBLE=130 SERVICE=300 ISIBLE=200
*/
if (appProcess.importance != android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
//后臺(tái)
isBackGroundStart = true;
return true;
} else {
//前臺(tái)
return false;
}
}
}
}
return false;
}
ActivityA.java
public class ActivityA extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_a);
}
@Override
protected void onResume() {
super.onResume();
if (AppUtils.isBackGroundStart){
//TODO 執(zhí)行操作
AppUtils.isBackGroundStart = false;
}
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onStop() {
super.onStop();
AppUtils.isBackground(ActivityA.this);
}
}
ActivityB.java
public class ActivityB extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
}
@Override
protected void onResume() {
super.onResume();
if (AppUtils.isBackGroundStart){
//TODO 執(zhí)行操作
AppUtils.isBackGroundStart = false;
}
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onStop() {
super.onStop();
AppUtils.isBackground(ActivityB.this);
}
}