android4.2 锁屏源码分析

笨人,大到浏览了android4.2 锁屏代码的流程,以及关键的几个类,及布局文件,用于备忘。


写得有点乱,等有时间再整理下。



//1 java层核心第一个类:(famework/base/service/java/com/android/server/)

SystemServer.javaà

//2 系统调用第一个类的入口init1()

native public static voidinit1(String[] args);à

//3 接着init1()通过jni回调init2()

public static final voidinit2() {

     

        Thread thr = new ServerThread();

       thr.setName("android.server.ServerThread");

//4 init2()开启自已的线程

        thr.start();

}  à

//5 线程开启调用run()

  public void run()à

//run()中,启动一系列service

 //6其中之一是:wm = WindowManagerService.main(context, power, display, inputManager,uiHandler, wmHandler, factoryTest !=SystemServer.FACTORY_TEST_LOW_LEVEL,!firstBoot, onlyCore);à

// 7 在main方法中,调用了WindowManagerService构造方法,构造方法中又在initPolicy中调用了(PhoneWindowManager)mPolicy.init(),该方法对PhoneWindowManager里面的重要变量,进行初始化。

//7 继续第5步中的run方法中,调用如下代码。

   try {

            wm.displayReady();

        } catch (Throwable e) {

            reportWtf("making display ready", e);

        }à

try {

//通知WindowManagerService.displayReady()系统已启动好:

            wm.systemReady();

      

Configuration config =wm.computeNewConfiguration();

 

à

---------------------------------------------------------

/*以下代码是WindowManagerService如何获取PhoneWindowManagermPolicy)引用的。

1 Frameworks/base/service/java/com/android/server/wm/WindowManagerService.javaà

//通过PolicyManager获取PhoneWindowManager对象。

final WindowManagerPolicy PhoneWindowManagermPolicy = PolicyManager.makeNewWindowManager();à

 

PolicyManager.javaà

Class policyClass = Class.forName(“com.android.internal.policy.impl.Policy”);

            sPolicy =(IPolicy)policyClass.newInstance();

publicstatic WindowManagerPolicy makeNewWindowManager() {

        return sPolicy.makeNewWindowManager();

}à

 

Policy.javaà

publicWindowManagerPolicy makeNewWindowManager() {

        return new PhoneWindowManager();

}

-------------------------------------------------------

//8 WindowManagerService.javaà

public void systemReady() {

//通知PhoneWindowManager系统启动好:

        (PhoneWindowManager)mPolicy.systemReady();à

    }

 

//9 PhoneWindowManager.java(implementsWindowManagerPolicy)

在PhoneWindowManager的init方法中,初始化了成员变量,

mWindowManager

mOrientationListener new

mKeyguardMediator = new KeyguardViewMediator(context, null);

mSettingsObserver new

mShortcutManager new

 

public void systemReady() {

       if (mKeyguardMediator != null) {

           // tell the keyguard 告知锁屏系统已好,可以开始工作了

           mKeyguardMediator.onSystemReady();

       }

       synchronized (mLock) {

           updateOrientationListenerLp(); //???????

           mSystemReady = true;

           mHandler.post(new Runnable() {

                public void run() {

                    updateSettings();//?????

                }

           });

       }

    }

 

// 10 mKeyguardMediator.onSystemReady():

KeyguardViewMediator.java

1 成员

    private AlarmManager mAlarmManager;

    private AudioManager mAudioManager;

    private PowerManager mPM;

    private UserManager mUserManager;

private PowerManager.WakeLock mShowKeyguardWakeLock;

private LockPatternUtils mLockPatternUtils;

*  mViewMediatorCallback—〉这个接口会给多view回调

 mUpdateCallback—

*  mUpdateMonitor

*   mKeyguardViewManager= new KeyguardViewManager(context, wm,mViewMediatorCallback,mLockPatternUtils);//这个类就是创建锁屏界面的类。

 

*  private StatusBarManager mStatusBarManager;

 

2 构造函数:

mKeyguardViewManage  <- mViewMediatorCallback

mUpdateMonitor= KeyguardUpdateMonitor.getInstance(context);

3

onSystemReady(){

mUpdateMonitor.registerCallback(mUpdateCallback);

  /// M:power-off alarm @{

            if (!KeyguardUpdateMonitor.isAlarmBoot()){

                doKeyguardLocked();//调用锁屏

            }

           /// @}

}

doKeyguardLocked():{

// 如果有第三方锁屏应用,就不显示锁屏

        if (!mExternallyEnabled || KeyguardUpdateMonitor.isAlarmBoot()){

           if (DEBUG) KeyguardUtils.xlogD(TAG,"doKeyguard:not showing because externally disabled");

return;

}

}

4 showLocked(Bundle options){

5 handleShow(Bundle options){

 

mKeyguardViewManager.show(options);

}

 

// 11 KeyguardViewManager:

 

----------------------------- 注  begin----------------------------

maybeCreateKeyguardLocked()本类中有三处调用:

a reset()方法,由mediator监听到系统某状态变化调用。

B onScreenturnon():由phonemanageràmediator调用。

C ViewManagerHost.onConfigchannged调用。(这个ViewManagerHost就是锁屏的根view)

----------------------------- 注  end----------------------------

 

mKeyguardViewManager.show(options){

//创建锁屏界面

maybeCreateKeyguardLocked(enableScreenRotation,false, options); ---》

maybeEnableScreenRotation(enableScreenRotation);

mKeyguardHost.setSystemUiVisibility(visFlags);

mViewManager.updateViewLayout(mKeyguardHost,mWindowLayoutParams);

mKeyguardHost.setVisibility(View.VISIBLE); //锁屏界面可见

mKeyguardView.show();//锁屏界面可见

mKeyguardView.requestFocus();//取得焦点

}

--》maybeCreateKeyguardLocked(){

if (mKeyguardHost ==null) {

          mKeyguardHost = new ViewManagerHost(mContext);

mViewManager.addView(mKeyguardHost,lp);//将锁屏界面加入到framelayout中

}

if (force && mKeyguardView != null) {

            mKeyguardView.cleanUp();//释放旧锁屏占用的空间。

        }

        if (force ||mKeyguardView == null) {

            inflateKeyguardView(options);//创建新的锁屏界面

        }

       updateUserActivityTimeoutInWindowLayoutParams();

        mViewManager.updateViewLayout(mKeyguardHost,mWindowLayoutParams);

 

       mKeyguardHost.restoreHierarchyState(mStateContainer);

--》inflateKeyguardView—这个方法将锁屏界面解析出view放到容器里。{

1 判断是否是闹钟启动-- KeyguardUpdateMonitor.isAlarmBoot()

2 移除之前的view.-- mKeyguardHost.removeView(v);  

3//解析layout锁屏布局,放到父容器中。

int layoutId = R.layout.keyguard_host_view;

mKeyguardView = (KeyguardHostView)view.findViewById(resId);

mKeyguardView.setLockPatternUtils(mLockPatternUtils);

mKeyguardView.setViewMediatorCallback(mViewMediatorCallback);

 

}

 

 

 

 

 

// 12 KeyguardHostView.java

一、先画一下布局:

1最外层是KeyguardHostView(间接继承自framelayout)+Id/keyguard_host_view

2 第二层SlidingChallengeLayout(继承自viewgroup)@+id/sliding_layout

3 再里面有七个东东

依次是:1) mediatekLayerBackground   

        2) +id/keyguard_widget_pager_delete_target:(TextView)删除目的地

3) <includelayout="@layout/keyguard_widget_pager"

     android:id="@+id/app_widget_container">  ViewGroupwidget容器。

   注:显示时间,日期的keyguard_status_view由方法addDefaultStatusWidget(intindex)add 进来。

4) 麻布

5)前景

6)KeyguardSecurityContainer(FrameLayout):@+id/keyguard_security_container

KeyguardSecurityViewFlipper(ViewFlipper):@+id/view_flipper

7)一个锁。

 

具体布局如下图所示:




<includelayout="@layout/keyguard_glow_pad_container" />

----à<includelayout="@layout/keyguard_glow_pad_view"

-------à

<com.android.internal.policy.impl.keyguard.MediatekGlowPadView

   xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"

   xmlns:android="http://schemas.android.com/apk/res/android"

   android:id="@+id/glow_pad_view"

   android:layout_width="wrap_content"

   android:layout_height="wrap_content"

   android:layout_gravity="center"

   android:orientation="horizontal"

   android:gravity="@integer/kg_selector_gravity"

   android:contentDescription="@string/keyguard_accessibility_slide_area"

   prvandroid:targetDrawables="@array/lockscreen_targets_unlock_only"

   prvandroid:targetDescriptions="@array/lockscreen_target_descriptions_unlock_only"

   prvandroid:directionDescriptions="@*android:array/lockscreen_direction_descriptions"

    prvandroid:handleDrawable="@*android:drawable/ic_lockscreen_handle"

   prvandroid:outerRingDrawable="@*android:drawable/ic_lockscreen_outerring"

   prvandroid:outerRadius="@*android:dimen/glowpadview_target_placement_radius"

   prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"

   prvandroid:snapMargin="@*android:dimen/glowpadview_snap_margin"

   prvandroid:firstItemOffset="@integer/kg_glowpad_rotation_offset"

   prvandroid:magneticTargets="true"

    prvandroid:feedbackCount="1"

   prvandroid:vibrationDuration="20"

   prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"

   prvandroid:pointDrawable="@*android:drawable/ic_lockscreen_glowdot"

   prvandroid:allowScaling="true" />

 

 

二、接下来看看:onFinishInflate()方法里做了什么。

1)mAppWidgetContainer.setCallbacks(mWidgetCallbacks);这个callback中,会控制锁屏界面的widget快捷界面最多为5个,方法是让+不可点击。

2)mAppWidgetContainer.setDeleteDropTarget(deleteDropTarget);删除的目的地。

3)addDefaultWidgets(): 添加加号,和相机widget.这里只有“滑动解锁”界面才会有相机界面。

其它解锁界面不会有,原因是进相机后就已解锁了。这对于其它解锁方式是不合适的。

 

4)addWidgetsFromSettings();//添加用户自定的widget以及默认界面。

5) mSwitchPageRunnable.run();//显示默认页。

6) showPrimarySecurityScreen(false);//根据安全模式显示界面。

updateSecurityViews();设置回调参数等

 

// 13  KeyguardSelectorView.java

成员变量:

private KeyguardSecurityCallbackmCallback;//回调

        privateMediatekGlowPadViewmGlowPadView;//动画pannal

private ObjectAnimator mAnim;

mOnTriggerListener:解锁回调监听器

 

成员方法:

onFinishInflate(){

mGlowPadView =(MediatekGlowPadView) findViewById(R.id.glow_pad_view);//解锁动画panel.

        mGlowPadView.setOnTriggerListener(mOnTriggerListener);

updateTargets();//ic_lockscreen_camera,ic_action_assist_generic

 

inflater.inflate(com.mediatek.internal.R.layout.keyguard_unread_event_view,unLockPanel, true);//未读事件的view读入并可见。

 

}

 

//14UnReadEventView.java:未读事件视图。

ViewGroup drawableView =(ViewGroup)layouterInfalter.inflate(R.layout.keyguard_new_event_view, this,false);

newEventView.setViewVisibility(View.VISIBLE);

               addView(drawableView);

 

 

 

//15 MediatekGlowPadView.java

 

构造函数:MediatekGlowPadView(){

mInnerRadius  = 15dip 内圈半径

mOuterRadius = 135dip外圈半径

mSnapMargin = 40dip

mFirstItemOffset = 0

mVibrationDuration = 0

mFeedbackCount =

mAllowScaling

mHandleDrawable =中间拖拽的锁图

mOuterRing =外圈白色

mAlwaysTrackFinger

mMagneticTargets

mGlowRadius白点增长半径

// Read array of target drawables

//下面这段,用于初始化解锁界面的圆环上有几种快捷解锁方式。mTargetDrawables

        if (a.getValue(R.styleable.GlowPadView_targetDrawables,outValue)) {

//上面一行代码是,将targetDrawables属性值对应的drawble数组资源里的图片全部读入,默认是一张解锁的//图片,如果想改成有多种快捷解锁方式,可以改这个drawble数组即可。

            internalSetTargetResources(outValue.resourceId);//计算每个targetDrawables的//元素的中心坐标以及与中心的相对坐标,用于在滑动解锁时判断是何快捷方式。

        }

        if (mTargetDrawables ==null || mTargetDrawables.size() == 0) {

            throw new IllegalStateException("Must specify at least one target drawable");

        }

}

//滑动解锁面板的onDraw()方法

  @Override

    protected void onDraw(Canvas canvas) {

        mPointCloud.draw(canvas);

        mOuterRing.draw(canvas);

        final int ntargets =mTargetDrawables.size();

        for (int i = 0; i < ntargets; i++) {

            TargetDrawable target =mTargetDrawables.get(i);

            if (target != null) {

                target.draw(canvas);

            }

        }

        mHandleDrawable.draw(canvas);

        if (mFakeHandleDrawable != null) {

            mFakeHandleDrawable.draw(canvas);

           updateHandleDrawablePositions(false);

        }

    }

// onTouchEvent方法:

   handleDown(event);//置状态,背景动画,动画,未读事件动画,画云。

    handleMove(event);//更改云的配置。在这个方法中,不断的根据当前的触点位置,计算该点到中心的距离,以及相对中心的角度,然后根据这距离与角度看是否与某个快捷图标角度匹配,并记住匹配项,赋值给mActiveTarget变量。

  if (activeTarget!= -1) {

            switchToState(STATE_SNAP, x,y);

            updateGlowPosition(x, y);

        } else {

            switchToState(STATE_TRACKING, x, y);

            updateGlowPosition(x, y);

        }

上面代码:是如果匹配到就隐藏handledrawable(就是中间的手柄)并置状态为STATE_SNAP否则就状态为STATE_TRACKING

 

updateTargetPosition()这个方法好像只是放中心坐标,位置坐标。

//下面分析dofinish()方法:

boolean targetHit = activeTarget != -1;//这个变量表示是否有目标被匹配。

highlightSelected(activeTarget);//高亮被选中的,隐藏没有选中的。

 

hideGlow//动画隐藏什么。

dispatchTriggerEvent(activeTarget);//调用解锁方法。

 

_pin_view;

           //case SimPuk: return R.layout.keyguard_sim_puk_view;

           case SimPinPuk1: returncom.mediatek.internal.R.layout.keyguard_sim_pin_puk_view;

           case SimPinPuk2: returncom.mediatek.internal.R.layout.keyguard_sim_pin_puk_view;

           /// @}

 

           /// M: power-off alarm @{

           case AlarmBoot: returncom.mediatek.internal.R.layout.power_off_alarm_view;

           /// @}

           ///M: add voice unlock view layout

           case Voice: return R.layout.zz_keyguard_voice_unlock_view;

           default:

                return 0;

       }

from:http://blog.csdn.net/summerxzg/article/details/8907720

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值