AndroidL分析之Keyguard
来源:互联网 发布:淘宝秋冬男旅游鞋 编辑:程序博客网 时间:2024/06/06 02:21
AndroidL 锁屏与SystemUI
AndroidL出来都这么久,AndroidM现在都有了,现在出来写这个是有点晚了,这里仅是当作自己的一个总结吧,希望新接触系统开发的人看到,能对他们有一点帮助。
在AndroidL之后(看了下M代码,基本还是跟L一样,没变化),谷歌把之前相对独立的Keyguard整合进了SystemUI之中,打开SystemUI目录可以看到很多Keyguard命名的文件。这应该是为了可以复用SystemUI通知部分代码,使系统通知可以在锁屏上显示。
但是这么一来,锁屏与SystemUI界面代码耦合,想要为系统锁屏单独增加个动画特效都变得异常艰难,对SystemUI的调整也要同时考虑到会不会对锁屏有影响。
这里先分析一下锁屏代码,以后再记录下怎么反Google,怎么样可以把系统锁屏独立出来的一些想法。由于AndroidKK锁屏流程分析,网上资源比较丰富,为节省篇幅,更多的是讨论AndroidL中锁屏与KK不太一样的地方。
锁屏启动过程
我们按照AndroidKK的思路,锁屏应该有一个service通过AIDL与系统进行交互,观察一下SystemUI中的代码结构,发现了KeyguardService.java
。其实keyguardService是在PhoneWindowManager
的systemBooted()
中启动的:
/** {@inheritDoc} */ @Override public void systemBooted() { if (mKeyguardDelegate != null) { mKeyguardDelegate.bindService(mContext);//通过mKeyguardDelegate以bind方式启动/连接锁屏服务。 mKeyguardDelegate.onBootCompleted(); } synchronized (mLock) { mSystemBooted = true; } wakingUp(); screenTurningOn(null); }
KeyguardService.java
的onCreate
函数如下:
@Override public void onCreate() { ((SystemUIApplication) getApplication()).startServicesIfNeeded(); mKeyguardViewMediator = ((SystemUIApplication) getApplication()).getComponent(KeyguardViewMediator.class); }
startServicesIfNeeded
定义在SystemUIApplication
中,是SystemUI用来初始化各个模块的入口。
再看下KeyguardServiceonBind
函数返回的binder对象:
private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() { private boolean mIsOccluded; @Override public boolean isShowing() { return mKeyguardViewMediator.isShowing(); } @Override public boolean isSecure() { return mKeyguardViewMediator.isSecure(); } @Override public boolean isShowingAndNotOccluded() { return mKeyguardViewMediator.isShowingAndNotOccluded(); } ... ...}
锁屏这样就跟系统服务PhoneWindowManager
绑定了,系统可以控制锁屏的显示,在来电时或者其他应用窗口请求暂时隐藏锁屏时,可以进行响应。KeyguardService
只是为系统提供一个查询和控制锁屏状态的入口。那么锁屏界面到底是如何加载显示到屏幕上的呢?
锁屏界面的加载显示
我们再倒回去看一下,startServicesIfNeeded
到底初始化了哪些模块。
/** * Makes sure that all the SystemUI services are running. If they are already running, this is a * no-op. This is needed to conditinally start all the services, as we only need to have it in * the main process. * * <p>This method must only be called from the main thread.</p> */ public void startServicesIfNeeded() { if (mServicesStarted) { return; } //省略判断开机状态代码 Log.v(TAG, "Starting SystemUI services."); final int N = SERVICES.length; for (int i=0; i<N; i++) { Class<?> cl = SERVICES[i];//各个模块Class if (DEBUG) Log.d(TAG, "loading: " + cl); try { mServices[i] = (SystemUI)cl.newInstance();//实例化 } catch (IllegalAccessException ex) { throw new RuntimeException(ex); } catch (InstantiationException ex) { throw new RuntimeException(ex); } mServices[i].mContext = this;//统一设置mContext mServices[i].mComponents = mComponents;//统一设置mComponents if (DEBUG) Log.d(TAG, "running: " + mServices[i]); mServices[i].start();//调用每个模块的start方法。 if (mBootCompleted) { mServices[i].onBootCompleted(); } } mServicesStarted = true; }
/** * The classes of the stuff to start. */ private final Class<?>[] SERVICES = new Class[] { com.android.systemui.keyguard.KeyguardViewMediator.class, com.android.systemui.recent.Recents.class, com.android.systemui.volume.VolumeUI.class, com.android.systemui.statusbar.SystemBars.class, com.android.systemui.usb.StorageNotification.class, com.android.systemui.power.PowerUI.class, com.android.systemui.media.RingtonePlayer.class };//所有的这些类都继承自`SystemUI`这个父类。Google的这个做法非常好的把每个模块分开初始化,又统一设置了同样的Context和Components。这个应该算是哪种设计模式呢???
我们找到了KeyguardViewMediator
这个重要的类,它现在被放到了
SystemUI\src\com\android\systemui\keyguard\
中。职责跟KK时代相比基本没变,负责管理锁屏界面的加载,控制密码锁、pin码锁等界面的显示。
KeyguardViewMediator的start方法很简单:
@Override public void start() { setup();//这个方法负责初始化变量和生成实例,AndroidKK是放到KeyguardViewMediator的onCreate中调用的。 putComponent(KeyguardViewMediator.class, this);//由于在startServicesIfNeeded中统一设置了统一的`mComponents`,所以当其他模块需要用到KeyguardViewMediator的时候,只需要简单的调用`getComponent`方法就可以取到同一个对象,这个设计真是·简单好用·。 }
setUp()
初始化AlarmManager
、PowerManager
等并加载了锁屏音,进行了一系列跟锁屏相关的初始化工作。
继续分析KeyguardViewMediator
代码handleShow
:
/** * Handle message sent by {@link #showLocked}. * @see #SHOW */ private void handleShow(Bundle options) { ... ... mStatusBarKeyguardViewManager.show(options); //忽略判断系统状态和其他的代码,关注这句,这个是跟布局显示相关的调用。 ... ... }
继续向下追踪代码到了StatusBarKeyguardViewManager
中的reset
函数:
/** * Reset the state of the view. */ public void reset() { if (mShowing) { if (mOccluded) {//occluded 变量判断当前锁屏是否需要被隐藏。(当前台Window有SHOW_WHEN_LOCKED属性的时候) mPhoneStatusBar.hideKeyguard(); mBouncer.hide(false /* destroyView */); } else { showBouncerOrKeyguard();//这一句。 } updateStates(); } }
往下看:
/** * Shows the notification keyguard or the bouncer depending on * {@link KeyguardBouncer#needsFullscreenBouncer()}. */ private void showBouncerOrKeyguard() { if (mBouncer.needsFullscreenBouncer()) {//当需要显示手机卡sim pin码锁屏的时候,返回true。 // The keyguard might be showing (already). So we need to hide it. mPhoneStatusBar.hideKeyguard(); mBouncer.show();//显示安全锁屏 } else { mPhoneStatusBar.showKeyguard();//显示传统意义上的锁屏。 mBouncer.hide(false /* destroyView */);//hide了什么? mBouncer.prepare(); } }
看到这里,我们可能会有疑惑:这个hideKeyguard
hide的是哪个keyguard
?这个mBouncer
又是个什么?也是锁屏吗?难道有两个锁屏在互相切换吗?
前面已经讲过,在AndroidL之后的代码中,锁屏布局的加载显示已经移到了SystemUI模块中。SystemUI这里的Keyguard
指的是:
而Bouncer
是加载安全锁屏的容器:
找到了PhoneStatusBar
和Bouncer
的调用以后,我们查看他们的布局文件,可以发现,锁屏是依附于SystemUI的布局文件进行加载的。我们看到的系统锁屏, 其实是把SystemUI拉下展开之后的一个特殊状态,在它上面可以很方便的显示系统通知 。这个是Google在AndroidL之后重新设计的。
这样可以方便的显示系统通知,但是锁屏View和SystemUI绑定到一起,如果要调整锁屏的布局和动画特效,就要小心可能会对SystemUI产生的影响,如果要更改锁屏的触摸操作、交互逻辑,很难不影响SystemUI。
我们看到华为荣耀的锁屏效果,解锁效果非常酷炫,UI元素和交互方式也比原生锁屏丰富,他们肯定是把锁屏独立出来了。
原文地址:http://www.codingpuppy.com/post/androidl/m-suo-ping-fen-xi
- AndroidL分析之Keyguard
- Android Framework------之Keyguard 简单分析
- Android Framework------之Keyguard 简单分析
- Android Framework------之Keyguard 简单分析
- Android Framework------之Keyguard 简单分析
- Android Framework------之Keyguard 简单分析
- Android Framework------之Keyguard 简单分析
- Android Framework------之Keyguard 简单分析
- AndroidL ANR分析整理
- AndroidL 开机展示Keyguard锁屏机制初探
- androidL init 进程源码分析
- android Keyguard分析
- 4.2 Keyguard 流程分析
- Android4.4之Keyguard
- Keyguard之LockPatternView学习
- Android 7.0 Keyguard流程分析
- Android 7.0 Keyguard流程分析
- keyguard
- unity 各AR插件对比
- android开发常见问题收录
- Springboot+Mybatis
- UVa 1587
- 宏基因组实战8. 分箱宏基因组binning, MqaxBin, MetaBin, VizBin
- AndroidL分析之Keyguard
- bxSlider
- 云星数据---Apache Flink实战系列(精品版)】:Flink流处理API详解与编程实战013-Flink在流处理中常见的sink和source002
- anduraljs的表格删除和查找关键字
- 宏基因组实战9. 组装assembly和分箱bin结果可视化—Anvi'o
- Sparsity constraint稀疏约束详解
- idea导入eclipse项目并部署到Tomcat流程
- java项目读取properties的几种方式
- I2C协议