windowIsTranslucent和windowBackground对比

  在Activity A切换到Activity B时,有时会遇到黑屏或者白屏的闪屏问题,经常我们会给Activity B设置一个透明主题来解决,即通过设置属性android:windowIsTranslucent=true或者android:windowBackground=@color/transparent。那么这两个属性有区别呢?下面从它们对Activity生命周期的影响来对比说明。

android:windowIsTranslucent 窗口是否设置为半透明
android:windowBackground 整个窗口的背景,包括边框和内部

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>

后台可见状态:onStart
用户可见状态: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中可以发现Activity A(MainActivity)切换到B时,只执行到了onPause方法,并没有执行onStop方法,所以在Activity B对用户可见时,下面的Activity A是处于部分可见的状态。

(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的生命周期执行顺序正常。

2、在Activity B页面,点击back键返回到A页面

(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)并未调用onStop方法,只调用了onPause,所以点击back键,Activity A要从onPause状态到对用户可见,只需要调用onResume方法(可上google官网查看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

  点击back键,Activity A从onStop状态到用户可见状态,需要调用onRestart、onStart、onResume方法,所以,点击back键也不会影响到activity的生命周期

3、停留在B页面,将应用从前台切到后台
(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时,A只调用了onPause方法,所以切到后台时,A到完全不可见,也调用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时,A已经完全不可见了,所以切到后台时,只有Activity B从可见到完全不可见,会调用onPause、onStop方法。

4、将应用切回前台
(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都从不可见状态(onStop)到可见的状态,只有B是到用户可见状态(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从不可见状态到用户可见的状态。

小结:
1、android:windowBackground不影响Activity的生命周期,即启动设置了该属性的Activity的生命周期不会受到影响。
2、android:windowIsTranslucent = true会影响到Activity的生命周期,比如启动一个设置了该属性的Activity,若该activity对用户可见时,启动它的activity(即它下层的activity)并未完全不可见(即调用到了onPause,不会调用onStop方法),具体可见上面的操作对Activity生命周期的影响。

优化:在实际开发中,发现对于Activity切换出现黑屏或者白屏处理中,若使用android:windowBackground对于7.0系统以上的手机还是会有闪屏的现象,若使用android:windowIsTranslucent = true就不会有闪屏现象,但是有两种情况需要进行优化:
1、需要在应用从前台切到后台时,执行操作。
判断是否切换后台的时机就需要放到onPause中去,若是切换后台,则执行操作。

2、需要在应用从后台切到前台时,执行操作。
若Activity A的上一层Activity B是透明主题,并且当前Activity B对用户完全可见的,此时Activity A处于onPause状态。
(1)停留在Activity B页面,应用从前台切换到后台时,Activity A也会执行onStop方法, 在onStop方法中判断应用是否切换到后台,是,将全局变量AppUtils.isBackGroundStart置为true,否则置为false。
(2)应用从后台切回前台时,当前只会有一个Activity会执行onResume方法(停留在Activity B页面时切到后台,所以切回前台时,只有Activity B会执行onResume), 此时可以通过全局变量isBackGroundStart判断应用是否是从后台切到前台的,执行需要在这个时机完成的操作后将isBackGroundStart置为false。

AppUtils.java

public static boolean isBackGroundStart = false;//是否从后台开启
   /**
     * 
     * 若Activity A的上一层Activity B是透明主题,并且当前Activity B对用户完全可见的,此时Activity A处于onPause状态。
     * 1、停留在Activity B页面,应用从前台切换到后台时,Activity A也会执行onStop方法,
     * 在onStop方法中判断应用是否切换到后台,是,将全局变量AppUtils.isBackGroundStart置为true,否则置为false。
     * 2、应用从后台切回前台时,当前只会有一个Activity会执行onResume方法(停留在Activity B页面时切到后台,所以切回前台时,只有Activity B会执行onResume),
     *  此时可以通过全局变量isBackGroundStart判断应用是否是从后台切到前台的,执行需要在这个时机完成的操作后将isBackGroundStart置为false。
     * !!!注意:这里的透明主题是指使用android:windowIsTranslucent = true设置窗口半透明
     * @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) {
                        //后台
                        isBackGroundStart = true;
                        return true;
                    } else {
                        //前台
                        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 执行操作

            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 执行操作

            AppUtils.isBackGroundStart = false;
        }
    }

   @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onStop() {
        super.onStop();
        AppUtils.isBackground(ActivityB.this);
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,333评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,812评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,016评论 0 246
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,293评论 0 214
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,650评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,788评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,003评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,741评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,462评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,681评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,168评论 1 262
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,528评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,169评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,119评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,902评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,846评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,719评论 2 274

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,580评论 25 707
  • 【Android Activity】 什么是 Activity? 四大组件之一,通常一个用户交互界面对应一个 ac...
    Rtia阅读 3,742评论 3 18
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,214评论 0 17
  • 本以为今天的日记又要落空了。看看这几天的记录就知道,残缺的、空白的,原来打了鸡血的自己呢?看来鸡血用光了。 好...
    江北_阅读 185评论 0 1
  • 昨天周末,公司有活动,本来是去加班的,早上走到中途,看到幸福俱乐部的链接分享,就果断掉头去活动现场了。 刚开始以为...
    潇洒君阅读 240评论 0 2