本文简单分析,android启动之后,锁屏界面启动过程。

android系统开机后会运行PhoneWindowManage管理系统相关按键和事件,

看下PhoneWindowManager锁屏相关

1.Pwm初始化KeyguardViewMediator类,用来接受PhoneWindowManager传递相关事件

2.系统启动完成会调用SystemReady函数,进入锁屏流程

/** {@inheritDoc} */  public void systemReady() {    // tell the keyguard    mKeyguardMediator.onSystemReady();    android.os.SystemProperties.set("dev.bootcomplete", "1");    synchronized (mLock) {      updateOrientationListenerLp();      mSystemReady = true;      mHandler.post(new Runnable() {        public void run() {          updateSettings();        }      });    }  }


3.KeyguradMediator中onSystemReady函数 /**
     * Let us know that the system is ready after startup.     */ public void onSystemReady() { synchronized (this) { if (DBG_WAKE) Log.d(TAG, "onSystemReady");            mSystemReady = true;            doKeyguardLocked(); } }


4.doKeyguardLocked进入锁屏判断,是否有第三方锁屏应用文件。
5.没有第三方锁屏应用或禁用锁屏,则进入showLocked函数 /**
 /**     * Send message to keyguard telling it to show itself     * @see #handleShow()     */    private void showLocked() {        if (DEBUG) Xlog.d(TAG, "showLocked");        // ensure we stay awake until we are finished displaying the keyguard        mShowKeyguardWakeLock.acquire();        Message msg = mHandler.obtainMessage(SHOW);                 if (isAlarmBoot() && !mChecked) {            mChecked = true;            Log.i(TAG, "it's alarm boot, delay 3s to show");            mHandler.sendMessageDelayed(msg, 5000);         } else {            mHandler.sendMessage(msg);         }    }


6.showLocked函数通过handler,发送显示锁屏信息或延时处理,handler 接受消息,直接调用handleShow处理
 /**     * Handle message sent by {@link #showLocked}.     * @see #SHOW     */    private void handleShow() {        synchronized (KeyguardViewMediator.this) {            if (DEBUG) Xlog.d(TAG, "handleShow");            if (!mSystemReady) return;            if (mShowing == true) return;            mShowCount++;            //avoid the int overflow            if (mShowCount == (int)Math.pow(2, 32)){                mShowCount=2;            }            Xlog.d(TAG, "handleShow, count="+mShowCount);            mKeyguardViewManager.show();            mShowing = true;            adjustUserActivityLocked();            adjustStatusBarLocked();                        try {                ActivityManagerNative.getDefault().closeSystemDialogs("lock");            } catch (RemoteException e) {            }            // Do this at the end to not slow down display of the keyguard.            playSounds(true);            mShowKeyguardWakeLock.release();        }    }


7.进入KeyguardViewManager中的show();KeyguardViewManager 是锁屏管理处理类,该类在KeyguraMeditor初始化
  /**     * Show the keyguard.  Will handle creating and attaching to the view manager     * lazily.     */    public synchronized void show() {        if (DEBUG) Xlog.d(TAG, "show(); mKeyguardView==" + mKeyguardView);        Resources res = mContext.getResources();        boolean enableScreenRotation =                SystemProperties.getBoolean("lockscreen.rot_override",false)                || res.getBoolean(R.bool.config_enableLockScreenRotation);        if (mKeyguardHost == null) {            if (DEBUG) Xlog.d(TAG, "keyguard host is null, creating it...");            mKeyguardHost = new KeyguardViewHost(mContext, mCallback);            final int stretch = ViewGroup.LayoutParams.MATCH_PARENT;            int flags = WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN                    | WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER                    | WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN                    | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;            if (mUpdateMonitor.DM_IsLocked()) {//in the first created                flags &= ~WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN;                flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;                flags |= WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;            } else {                flags &= ~WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;                flags &= ~WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;                flags |= WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN;            }            if (!mNeedsInput) {                flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;            }            if (ActivityManager.isHighEndGfx(((WindowManager)mContext.getSystemService(                    Context.WINDOW_SERVICE)).getDefaultDisplay())) {                flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;            }            WindowManager.LayoutParams lp = new WindowManager.LayoutParams(                    stretch, stretch, WindowManager.LayoutParams.TYPE_KEYGUARD,                    flags, PixelFormat.TRANSLUCENT);            lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;            lp.windowAnimations = com.android.internal.R.style.Animation_LockScreen;            if (ActivityManager.isHighEndGfx(((WindowManager)mContext.getSystemService(                    Context.WINDOW_SERVICE)).getDefaultDisplay())) {                lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;                lp.privateFlags |=                        WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;            }            lp.setTitle("Keyguard");            mWindowLayoutParams = lp;            mViewManager.addView(mKeyguardHost, lp);        }        if (enableScreenRotation || FeatureOption.MTK_TB_APP_LANDSCAPE_SUPPORT) {            if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen On!");            mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;        } else {            if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen Off!");            mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;        }        mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);        if (mKeyguardView == null) {            if (DEBUG) Xlog.d(TAG, "keyguard view is null, creating it...");            mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this);            mKeyguardView.setId(R.id.lock_screen);            mKeyguardView.setCallback(mCallback);            final ViewGroup.LayoutParams lp = new FrameLayout.LayoutParams(                    ViewGroup.LayoutParams.MATCH_PARENT,                    ViewGroup.LayoutParams.MATCH_PARENT);            mKeyguardHost.addView(mKeyguardView, lp);            if (mScreenOn) {                mKeyguardView.show();            }        }        // Disable aspects of the system/status/navigation bars that are not appropriate or        // useful for the lockscreen but can be re-shown by dialogs or SHOW_WHEN_LOCKED activities.        // Other disabled bits are handled by the KeyguardViewMediator talking directly to the        // status bar service.        int visFlags = ( View.STATUS_BAR_DISABLE_BACK                | View.STATUS_BAR_DISABLE_HOME);                mKeyguardHost.setSystemUiVisibility(visFlags);        mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);        mKeyguardHost.setVisibility(View.VISIBLE);        mKeyguardView.requestFocus();    }


show函数主要锁屏界面添加到ViewManager中显示,主要看下KeyguardView创建工程

mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this);
看下mKeyguraViewProperties 通过源码可知KeyViewMediator初始化创建,传入

KeyguardViewManager mKeyguardViewProperties = new LockPatternKeyguardViewProperties(mLockPatternUtils, mUpdateMonitor);

mKeyguardViewManager = new KeyguardViewManager( context, WindowManagerImpl.getDefault(), this, mKeyguardViewProperties, mUpdateMonitor);
8.LockPatternKeyguardViewProperties类中CreateKeyGuardView函数,初始化 LockPatternKeyguardView,LockPatternKeyguardView便是我们的锁屏界面

/** * Knows how to create a lock pattern keyguard view, and answer questions about * it (even if it hasn't been created, per the interface specs). */public class LockPatternKeyguardViewProperties implements KeyguardViewProperties {    private final LockPatternUtils mLockPatternUtils;    private final KeyguardUpdateMonitor mUpdateMonitor;    /**     * @param lockPatternUtils Used to know whether the pattern enabled, and passed     *   onto the keygaurd view when it is created.     * @param updateMonitor Used to know whether the sim pin is enabled, and passed     *   onto the keyguard view when it is created.     */    public LockPatternKeyguardViewProperties(LockPatternUtils lockPatternUtils,            KeyguardUpdateMonitor updateMonitor) {        mLockPatternUtils = lockPatternUtils;        mUpdateMonitor = updateMonitor;    }    public KeyguardViewBase createKeyguardView(Context context,            KeyguardUpdateMonitor updateMonitor,            KeyguardWindowController controller) {        return new LockPatternKeyguardView(context, updateMonitor,                mLockPatternUtils, controller);    }    public boolean isSecure() {        return mLockPatternUtils.isSecure() || isSimPinSecure();    }    private boolean isSimPinSecure() {        final IccCard.State simState = mUpdateMonitor.getSimState(Phone.GEMINI_SIM_1);        final IccCard.State sim2State = mUpdateMonitor.getSimState(Phone.GEMINI_SIM_2);        return (simState == IccCard.State.PIN_REQUIRED                || simState == IccCard.State.PUK_REQUIRED                || simState == IccCard.State.PERM_DISABLED                || sim2State == IccCard.State.PIN_REQUIRED                || sim2State == IccCard.State.PUK_REQUIRED                || sim2State == IccCard.State.PERM_DISABLED                || simState == IccCard.State.ABSENT                && sim2State == IccCard.State.ABSENT);    }}9.看下LockPatternKeyguardView初始流程    /**     * @param context Used to inflate, and create views.     * @param updateMonitor Knows the state of the world, and passed along to each     *   screen so they can use the knowledge, and also register for callbacks     *   on dynamic information.     * @param lockPatternUtils Used to look up state of lock pattern.     */    public LockPatternKeyguardView(            Context context,            KeyguardUpdateMonitor updateMonitor,            LockPatternUtils lockPatternUtils,            KeyguardWindowController controller) {        super(context);        mHandler = new Handler(this);        mConfiguration = context.getResources().getConfiguration();        mEnableFallback = false;        mRequiresSim = TextUtils.isEmpty(SystemProperties.get("keyguard.no_require_sim"));        mUpdateMonitor = updateMonitor;        mLockPatternUtils = lockPatternUtils;        mWindowController = controller;        mHasOverlay = false;        mUpdateMonitor.registerDeviceInfoCallback(this);        mUpdateMonitor.registerPhoneStateCallback(this);        mKeyguardScreenCallback = new KeyguardScreenCallback() {            public void goToLockScreen() {                mForgotPattern = false;                if (mIsVerifyUnlockOnly) {                    // navigating away from unlock screen during verify mode means                    // we are done and the user failed to authenticate.                    mIsVerifyUnlockOnly = false;                    getCallback().keyguardDone(false);                } else {                    updateScreen(Mode.LockScreen, false);                }            }            public void goToUnlockScreen() {                final IccCard.State simState = mUpdateMonitor.getSimState(Phone.GEMINI_SIM_1);                final IccCard.State sim2State = mUpdateMonitor.getSimState(Phone.GEMINI_SIM_2);                if (stuckOnLockScreenBecauseSimMissing()                    || (simState == IccCard.State.PUK_REQUIRED                     && !mLockPatternUtils.isPukUnlockScreenEnable())                    || (sim2State == IccCard.State.PUK_REQUIRED                     && !mLockPatternUtils.isPukUnlockScreenEnable())){                    // stuck on lock screen when sim missing or                    // puk'd but puk unlock screen is disabled                    return;                }                if (!isSecure()) {                    getCallback().keyguardDone(true);                } else {                    updateScreen(Mode.UnlockScreen, false);                }            }            public void forgotPattern(boolean isForgotten) {                if (mEnableFallback) {                    mForgotPattern = isForgotten;                    updateScreen(Mode.UnlockScreen, false);                }            }            public boolean isSecure() {                return LockPatternKeyguardView.this.isSecure();            }            public boolean isVerifyUnlockOnly() {                return mIsVerifyUnlockOnly;            }            public void recreateMe(Configuration config) {                removeCallbacks(mRecreateRunnable);                post(mRecreateRunnable);            }            public void takeEmergencyCallAction() {                mHasOverlay = true;                // Continue showing FaceLock area until dialer comes up or call is resumed                if (mLockPatternUtils.usingBiometricWeak() &&                        mLockPatternUtils.isBiometricWeakInstalled() && mFaceLockServiceRunning) {                    showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_EMERGENCY_DIALER_TIMEOUT);                }                // FaceLock must be stopped if it is running                stopAndUnbindFromFaceLock();                pokeWakelock(EMERGENCY_CALL_TIMEOUT);                if (TelephonyManager.getDefault().getCallState()                        == TelephonyManager.CALL_STATE_OFFHOOK) {                    mLockPatternUtils.resumeCall();                } else {                    Intent intent = new Intent(ACTION_EMERGENCY_DIAL);                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK                            | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                    getContext().startActivity(intent);                }            }            public void pokeWakelock() {                getCallback().pokeWakelock();            }            public void pokeWakelock(int millis) {                getCallback().pokeWakelock(millis);            }            public void keyguardDone(boolean authenticated) {                getCallback().keyguardDone(authenticated);                mSavedState = null; // clear state so we re-establish when locked again            }            public void keyguardDoneDrawing() {                // irrelevant to keyguard screen, they shouldn't be calling this            }            public void reportFailedUnlockAttempt() {                mUpdateMonitor.reportFailedAttempt();                final int failedAttempts = mUpdateMonitor.getFailedAttempts();                if (DEBUG) Xlog.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts +                    " (enableFallback=" + mEnableFallback + ")");                final boolean usingPattern = mLockPatternUtils.getKeyguardStoredPasswordQuality()                        == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;                final int failedAttemptsBeforeWipe = mLockPatternUtils.getDevicePolicyManager()                        .getMaximumFailedPasswordsForWipe(null);                final int failedAttemptWarning = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET                        - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;                final int remainingBeforeWipe = failedAttemptsBeforeWipe > 0 ?                        (failedAttemptsBeforeWipe - failedAttempts)                        : Integer.MAX_VALUE; // because DPM returns 0 if no restriction                if (remainingBeforeWipe < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_WIPE_GRACE) {                    // If we reach this code, it means the user has installed a DevicePolicyManager                    // that requests device wipe after N attempts.  Once we get below the grace                    // period, we'll post this dialog every time as a clear warning until the                    // bombshell hits and the device is wiped.                    if (remainingBeforeWipe > 0) {                        showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe);                    } else {                        // Too many attempts. The device will be wiped shortly.                        Slog.i(TAG, "Too many unlock attempts; device will be wiped!");                        showWipeDialog(failedAttempts);                    }                } else {                    boolean showTimeout =                        (failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) == 0;                    if (usingPattern && mEnableFallback) {                        if (failedAttempts == failedAttemptWarning) {                            showAlmostAtAccountLoginDialog();                            showTimeout = false; // don't show both dialogs                        } else if (failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) {                            mLockPatternUtils.setPermanentlyLocked(true);                            updateScreen(mMode, false);                            // don't show timeout dialog because we show account unlock screen next                            showTimeout = false;                        }                    }                    if (showTimeout) {                        showTimeoutDialog();                    }                }                mLockPatternUtils.reportFailedPasswordAttempt();            }            public boolean doesFallbackUnlockScreenExist() {                return mEnableFallback;            }            public void reportSuccessfulUnlockAttempt() {                mFailedFaceUnlockAttempts = 0;                mLockPatternUtils.reportSuccessfulPasswordAttempt();            }        };        /**         * We'll get key events the current screen doesn't use. see         * {@link KeyguardViewBase#onKeyDown(int, android.view.KeyEvent)}         */        setFocusableInTouchMode(true);        setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);        updateScreen(getInitialMode(), false);        maybeEnableFallback(context);    }

10.updateScreen,根据当前锁屏模式,更新显示相应的锁屏界面,

private void updateScreen(Mode mode, boolean force) {        Log.v(TAG, "**** UPDATE SCREEN: mode=" + mode                + " last mode=" + mMode + ", force = " + force);        mMode = mode;        // Re-create the lock screen if necessary        if (mode == Mode.LockScreen || mShowLockBeforeUnlock) {            if (force || mLockScreen == null) {                recreateLockScreen();            }        }        // Re-create the unlock screen if necessary. This is primarily required to properly handle        // SIM state changes. This typically happens when this method is called by reset()        if (mode == Mode.UnlockScreen) {            final UnlockMode unlockMode = getUnlockMode();            if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {                recreateUnlockScreen(unlockMode);            }        }        // visibleScreen should never be null        final View goneScreen = (mode == Mode.LockScreen) ? mUnlockScreen : mLockScreen;        final View visibleScreen = (mode == Mode.LockScreen) ? mLockScreen : mUnlockScreen;        // do this before changing visibility so focus isn't requested before the input        // flag is set        mWindowController.setNeedsInput(((KeyguardScreen)visibleScreen).needsInput());        if (DEBUG_CONFIGURATION) {            Xlog.v(TAG, "Gone=" + goneScreen);            Xlog.v(TAG, "Visible=" + visibleScreen);        }        if (mScreenOn) {            if (goneScreen != null && goneScreen.getVisibility() == View.VISIBLE) {                ((KeyguardScreen) goneScreen).onPause();            }            if (visibleScreen.getVisibility() != View.VISIBLE) {                ((KeyguardScreen) visibleScreen).onResume();            }        }        if (goneScreen != null) {            goneScreen.setVisibility(View.GONE);        }        visibleScreen.setVisibility(View.VISIBLE);        requestLayout();        if (!visibleScreen.requestFocus()) {            throw new IllegalStateException("keyguard screen must be able to take "                    + "focus when shown " + visibleScreen.getClass().getCanonicalName());        }    }


11.recreateLockScreen(),创建锁屏

  private void recreateLockScreen() {        Log.i(TAG, "recreateLockScreen");        if (mLockScreen != null) {            ((KeyguardScreen) mLockScreen).onPause();            ((KeyguardScreen) mLockScreen).cleanUp();            removeView(mLockScreen);        }        mLockScreen = createLockScreen();        mLockScreen.setVisibility(View.INVISIBLE);        addView(mLockScreen);    }

   

更多相关文章

  1. android用户界面-组件Widget-网格视图GridView
  2. android Preference视图的使用
  3. Android(安卓)频道管理仿今日头条
  4. Android(安卓)应用界面开发笔记
  5. android:dkplayer中ijkplayer延迟长的问题,达到秒开的结果
  6. Android的Linux内核的电源管理:Early Suspend
  7. android init 进程分析 (2 初始化流程)
  8. Android(安卓)OpenGLES 实现结构
  9. static 和 visibility hidden 的区别

随机推荐

  1. Node.js与Android(安卓)SDK的下载与部署
  2. 【10.2移动新特性】好用的Application Fr
  3. Android中的FlexboxLayout
  4. Android中MenuInflater实例
  5. android app 不会被low memory killer回
  6. 在配置最新Androi adt20.0.0 遇到的一些
  7. CSS3实现android(安卓)Logo图标效果
  8. Qt 实现android camera摄像头的preview和
  9. android检测网络是否正常
  10. android UI设计属性中英对照表(未修订)