preface

There is a problem here. The height of the status bar has been set to 0 by the system, but the time and WiFi ICONS cannot be seen on the interface, and the notification bar cannot be displayed by pulling down. However, in some applications, the status bar of the activity is still displayed. This bar is thought to be the title bar of the activity at first, but later, it is found to be the status bar.

The application layer changes the window style of the Activity

The status bar can be hidden in the activity’s onCreate method:

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Window window = getWindow(); window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // Hide the status bar setContentView(r.layout.activity_main); }Copy the code

Note that all window properties, such as hiding the navigation bar, hiding the title bar, and changing the color of the status bar, must be set before calling the following methods:

setContentView(R.layout.activity_main);
Copy the code

This is because, when the method is executed, it starts to get the related properties of the window, and then to draw the window. If you set the properties after this, an error or invalid setting will occur.

Change the Activity’s window style through the system

However, there are many apps involved in modification this time, so I want to implement it through the system and completely remove the status bar.

Since methods can be used to solve the problem in the application layer, we simply need to search the source code for the implementation of setContentView, and then find the appropriate location to set before drawing the window.

SetContentView belongs to the activity method, and we’ll look at the implementation of this method:

frameworks/base/core/java/android/app/Activity.java
public void setContentView(View view) {
    getWindow().setContentView(view);
    initWindowDecorActionBar();
}
Copy the code

The getWindow method is used to get an instance and then call the methods in that instance. Let’s start with the getWindow implementation:

frameworks/base/core/java/android/app/Activity.java
public Window getWindow() {
    return mWindow;
}
Copy the code

We return a global instance that is implemented in the Attach method of our activity:

frameworks/base/core/java/android/app/Activity.java
final void attach(Context context, ActivityThread aThread,
        Instrumentation instr, IBinder token, int ident,
        Application application, Intent intent, ActivityInfo info,
        CharSequence title, Activity parent, String id,
        NonConfigurationInstances lastNonConfigurationInstances,
        Configuration config, String referrer, IVoiceInteractor voiceInteractor,
        Window window, ActivityConfigCallback activityConfigCallback) {
        
    ....
    mWindow = new PhoneWindow(this, window, activityConfigCallback);
    mWindow.setWindowControllerCallback(this);
    mWindow.setCallback(this);
    mWindow.setOnWindowDismissedCallback(this);
    mWindow.getLayoutInflater().setPrivateFactory(this);
    if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
        mWindow.setSoftInputMode(info.softInputMode);
    }
    if (info.uiOptions != 0) {
        mWindow.setUiOptions(info.uiOptions);
    }
    
    ....
    mWindow.setWindowManager(
            (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
            mToken, mComponent.flattenToString(),
            (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
    if (mParent != null) {
        mWindow.setContainer(mParent.getWindow());
    }
    mWindowManager = mWindow.getWindowManager();
    mCurrentConfig = config;

    mWindow.setColorMode(info.colorMode);
    
    ...
}
Copy the code

The PhoneWindow method is used to implement the PhoneWindow method.

frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java public void setContentView(View view, ViewGroup.LayoutParams params) { // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window // decor, when theme attributes and the like are crystalized. Do not check the feature // before this happens. if (mContentParent == null) { installDecor(); } else if (! hasFeature(FEATURE_CONTENT_TRANSITIONS)) { mContentParent.removeAllViews(); } if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) { view.setLayoutParams(params); final Scene newScene = new Scene(mContentParent, view); transitionTo(newScene); } else { mContentParent.addView(view, params); } mContentParent.requestApplyInsets(); final Callback cb = getCallback(); if (cb ! = null && ! isDestroyed()) { cb.onContentChanged(); } mContentParentExplicitlySet = true; }Copy the code

If mContentParent is null when the activity is started for the first time, the installDecor method is executed.

frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java private void installDecor() { .... if (mContentParent == null) { mContentParent = generateLayout(mDecor); . }... }Copy the code

GenerateLayout mContentParent obtains an instance from generateLayout.

frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java protected ViewGroup generateLayout(DecorView decor) { TypedArray a = getWindowStyle(); final Context context = getContext(); final Context context = getContext(); . mIsFloating = a.getBoolean(R.styleable.Window_windowIsFloating, false); int flagsToUpdate = (FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR) & (~getForcedWindowFlags()); if (mIsFloating) { setLayout(WRAP_CONTENT, WRAP_CONTENT); setFlags(0, flagsToUpdate); } else { setFlags(FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR, flagsToUpdate); } if (a.getBoolean(R.styleable.Window_windowNoTitle, false)) { requestFeature(FEATURE_NO_TITLE); } else if (a.getBoolean(R.styleable.Window_windowActionBar, false)) { // Don't allow an action bar if there is no title. requestFeature(FEATURE_ACTION_BAR); } if (a.getBoolean(R.styleable.Window_windowActionBarOverlay, false)) { requestFeature(FEATURE_ACTION_BAR_OVERLAY); } if (a.getBoolean(R.styleable.Window_windowActionModeOverlay, false)) { requestFeature(FEATURE_ACTION_MODE_OVERLAY); } if (a.getBoolean(R.styleable.Window_windowSwipeToDismiss, false)) { requestFeature(FEATURE_SWIPE_TO_DISMISS); } / / add by MNQ. Hide status bar @ {the if (context) getResources (). GetBoolean (r. b ool. Cvte_hide_activity_statusbar) | | a.getBoolean(R.styleable.Window_windowFullscreen, false)) { setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN & (~getForcedWindowFlags())); } @} if (a.goboolean (r.tyleable.window_windowtranslucentStatus, false)) { setFlags(FLAG_TRANSLUCENT_STATUS, FLAG_TRANSLUCENT_STATUS & (~getForcedWindowFlags())); }... }Copy the code

The moment I made eye contact with getWindowStyle, I knew we had found the place. Here we find our target:

if ( a.getBoolean(R.styleable.Window_windowFullscreen, false)) {
        setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN & (~getForcedWindowFlags()));
}
Copy the code

If the Window is displayed in full screen, set FLAG_FULLSCREEN to FLAG_FULLSCREEN. Then, when the Window is drawn, it will be displayed in full screen without the status bar.

This resource configuration is the Window style configured in the Androidmanifest of each APP. Obviously we can’t change this. But we can add a configuration here and implement it in overlay:

1. frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java //add by mnq. Hide status bar @ {the if (context) getResources (). GetBoolean (r. b ool. Cvte_hide_activity_statusbar) | | a.getBoolean(R.styleable.Window_windowFullscreen, false)) { setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN & (~getForcedWindowFlags())); } / / add by MNQ. Hide status bar @} 2. Frameworks/base/core/res/res/values/config. The XML <! @{--> <bool name="cvte_hide_activity_statusbar">false</bool> <! -- add by MNQ. Hide status bar @} -- > 3. Frameworks/base/core/res/res/values/symbols. The XML <! <java-symbol type="bool" name="cvte_hide_activity_statusbar" /> <! -- Add by MNQ. Hide status @} -->Copy the code

This is equivalent to adding a configuration to the system that uses overlay to configure whether to force the activity’s status bar to be hidden from the system.

conclusion

Therefore, all window styles configured in Androidmanifest can be forcibly rewritten by the system here.

Of course, it would be nice to be able to configure it in Androidmanifest.

interactive

If the article has the wrong description, can leave a message directly, discuss together!

Articles that may be of interest

Step hole default input method configuration

Tread hole NavigationBar hidden or not

Android9.0 boot black screen for a while before loading the interface launcher solution

The last

I also write articles in wechat public number, update more timely, interested people can pay attention to the following public number!