1.下拉通知栏简介

 

2.源码位置

SystemUIService.javaframeworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.javaSystemUIApplication.javaframeworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.javaSystemBars.javaframeworks/base/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.javaconfig_statusBarComponentframeworks/base/packages/SystemUI/res/values/config.xmlServiceMonitor.javaframeworks/base/packages/SystemUI/src/com/android/systemui/statusbar/ServiceMonitor.javaPhoneStatusBar.javaframeworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.javaBaseStatusBar.javaframeworks/base/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.javaPhoneStatusBarView.javaframeworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.javasuper_status_bar.xmlframeworks/base/packages/SystemUI/res/layout/super_status_bar.xmlstatus_bar.xmlframeworks/base/packages/SystemUI/res/layout/status_bar.xmlsystem_icons.xmlframeworks/base/packages/SystemUI/res/layout/system_icons.xmlsignal_cluster_view.xmlframeworks/base/packages/SystemUI/res/layout/signal_cluster_view.xml

3. Status Bar启动流程

1. 当系统BOOT_COMPLETED后,SystemUIService会由SystemServer启动;之后 SystemUIApplication会启动依赖的几个服务。private final Class[] SERVICES = new Class[] {com.android.systemui.tuner.TunerService.class,com.android.systemui.keyguard.KeyguardViewMediator.class,com.android.systemui.recents.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,
};2. SystemBars启动后经由ServiceMonitor后, 启动config.xm中配置的StatusBar类。com.android.systemui.statusbar.phone.PhoneStatusBar3.  通过PhoneStatusBar和父类BaseStatusBar的start()方法,最终makeStatusBarView()被调用。protected PhoneStatusBarView makeStatusBarView() {
// 加载StatusBarWindowView视图,该视图包括Status bar/Quick Settings/Notification Panel
mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
R.layout.super_status_bar, null);
mStatusBarWindow.setService(this);
// 监听OnTouch事件,当下拉时展开Notification Panel
mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {checkUserAutohide(v, event);if (event.getAction() == MotionEvent.ACTION_DOWN) {if (mExpandedVisible) {animateCollapsePanels();}}return mStatusBarWindow.onTouchEvent(event);}
});
// 获取Status bar视图
mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
mStatusBarView.setBar(this);
// 将Status bar视图传递给StatusBarIconController
mIconController = new StatusBarIconController(
mContext, mStatusBarView, mKeyguardStatusBar, this);
// Other icons
// 电量控制类
mBatteryController = new BatteryController(mContext);
// 网络控制类
mNetworkController = new NetworkControllerImpl(mContext, mHandlerThread.getLooper());
// 安全控制类
mSecurityController = new SecurityControllerImpl(mContext);
// 信号簇视图,包括VPN/WIFI/手机信号等
final SignalClusterView signalCluster =
(SignalClusterView) mStatusBarView.findViewById(R.id.signal_cluster);
// 绑定网络控制器
mNetworkController.addSignalCallback(signalCluster);
// 绑定完全控制器
signalCluster.setSecurityController(mSecurityController);// 绑定网络控制器
signalCluster.setNetworkController(mNetworkController);
// 绑定电量控制器((BatteryMeterView)  mStatusBarView.findViewById(R.id.battery)).setBatteryController(mBatteryController);
// Set up the quick settings tile panelAutoReinflateContainer container = (AutoReinflateContainer)                 mStatusBarWindow.findViewById(R.id.qs_auto_reinflate_container);//下拉通知栏总区域if (container != null) {final QSTileHost qsh =      SystemUIFactory.getInstance().createQSTileHost(mContext, this,mBluetoothController, //蓝牙mLocationController,  //地址mRotationLockController,//自动旋转mNetworkController,   //数据开关mZenModeController,   //勿扰模式mHotspotController,   //热点mCastController,      //投射mFlashlightController,//手电筒mUserSwitcherController, // 不显示mUserInfoController,     // 不显示mKeyguardMonitor,   // 不显示mSecurityController, // 不显示mBatteryController,  // 电池管理mIconController,   // 不显示mNextAlarmController,// 不显示mHotKnotController,  // 热点mRingController,    //铃声模式mNfcController     //NFC);mBrightnessMirrorController= new   BrightnessMirrorController(mStatusBarWindow);container.addInflateListener(new InflateListener() {@Overridepublic void onInflated(View v) {QSContainer qsContainer = (QSContainer) v.findViewById(R.id.quick_settings_container);//qs_panel.xmlqsContainer.setHost(qsh);mQSPanel = qsContainer.getQsPanel();//QSPanel:下拉第一阶段快捷键显示条mQSPanel.setBrightnessMirror(mBrightnessMirrorController);mKeyguardStatusBar.setQSPanel(mQSPanel);mHeader =                                                                           qsContainer.getHeader();//quick_status_bar_expanded_header.xml        initSignalCluster(mHeader);mHeader.setActivityStarter(PhoneStatusBar.this);}});}}
SystemUIFactory.java
public QSTileHost createQSTileHost(Context context, PhoneStatusBar statusBar,BluetoothController bluetooth, LocationController location,RotationLockController rotation, NetworkController network,ZenModeController zen, HotspotController hotspot,CastController cast, FlashlightController flashlight,UserSwitcherController userSwitcher, UserInfoController userInfo,KeyguardMonitor keyguard, SecurityController security,BatteryController battery, StatusBarIconController iconController,NextAlarmController nextAlarmController,HotKnotController hotKnotController, RingController Ring,NfcController nfc)
{
return new QSTileHost(context, statusBar, bluetooth, location, rotation, network, zen,hotspot, cast, flashlight, userSwitcher, userInfo, keyguard, security, battery,iconController, nextAlarmController, hotKnotController, Ring,nfc);
}QSTileHost.java:
public QSTileHost(Context context, PhoneStatusBar statusBar,BluetoothController bluetooth, LocationController location,RotationLockController rotation, NetworkController network,ZenModeController zen, HotspotController hotspot,CastController cast, FlashlightController flashlight,UserSwitcherController userSwitcher, UserInfoController userInfo,KeyguardMonitor keyguard, SecurityController security,BatteryController battery, StatusBarIconController iconController,NextAlarmController nextAlarmController,HotKnotController hotknot, RingController Ring, NfcController nfc) {mContext = context;…......//TILES_SETTING = "sysui_qs_tiles";TunerService.get(mContext).addTunable(this, TILES_SETTING);…......}TunerService.java:........
public interface Tunable {void onTuningChanged(String key, String newValue);
}//QSTileHost implements QSTile.Host, Tunable
public void addTunable(Tunable tunable, String... keys) {//keys = sysui_qs_tilesfor (String key : keys) {addTunable(tunable, key);}}private void addTunable(Tunable tunable, String key) {//key = sysui_qs_tiles…........
String value = Settings.Secure.getStringForUser(mContentResolver, key, mCurrentUser);
Log.d("ylxing", "addTunable_value:"+ ((value == null)? "null":value));
tunable.onTuningChanged(key, value);//key = sysui_qs_tiles value == null
}QSTileHost.java:
@Override
public void onTuningChanged(String key, String newValue) {//key = sysui_qs_tilesif (!TILES_SETTING.equals(key)) {return;}final ListtileSpecs = loadTileSpecs(mContext, newValue);.......if (tileSpecs.equals(mTileSpecs) && currentUser == mCurrentUser)return;.......final LinkedHashMap> newTiles = new LinkedHashMap<>();for (String tileSpec : tileSpecs) {.......QSTiletile = mTiles.get(tileSpec);if (tile != null&& (!(tile instanceof CustomTile) || ((CustomTile) tile).getUser() == currentUser)) {tile.removeCallbacks();newTiles.put(tileSpec, tile);} else {try {tile = createTile(tileSpec);//QSTitleif (tile != null && tile.isAvailable()) {tile.setTileSpec(tileSpec);newTiles.put(tileSpec, tile);}} catch (Throwable t) {Log.w(TAG, "Error creating tile for spec: " + tileSpec, t);}}}mCurrentUser = currentUser;mTileSpecs.clear();mTileSpecs.addAll(tileSpecs); //默认快捷键"名称"容器mTiles.clear();mTiles.putAll(newTiles);//默认快捷键"实体键"容器for (int i = 0; i < mCallbacks.size(); i++) {mCallbacks.get(i).onTilesChanged();}}protected ListloadTileSpecs(Context context, String tileList) {if (tileList == null) {tileList = context.getResources().getString(R.string.quick_settings_tiles);// defaultLog.d(TAG, "Loaded tile specs from config: " + tileList);} else {Log.d(TAG, "Loaded tile specs from setting: " + tileList);}final ArrayListtiles = new ArrayList(); boolean addedDefault = false; for (String tile : tileList.split(",")) { tile = tile.trim(); if (tile.isEmpty()) continue; if (tile.equals("default")) { if (!addedDefault) { String defaultTiles = loadDefaultTiles(context); tiles.addAll(Arrays.asList(defaultTiles.split(","))); addedDefault = true; } } else { tiles.add(tile); } } return tiles; } /** * 默认显示Titles */ private String loadDefaultTiles(Context context) { final Resources res = context.getResources(); boolean enableNFC = res.getBoolean(R.bool.feature_systemui_nfc_support); boolean enableAlexa = res .getBoolean(com.android.internal.R.bool.def_tctfw_alexa_enable); boolean enableBatter = res .getBoolean(com.android.internal.R.bool.feature_tctfw_batterysaver_force_enable); boolean enable2017Music = res .getBoolean(com.android.internal.R.bool.feature_control_2017music_support); String defaultTiles = "wifi,bt,cell," + "ring,airplane,rotation," "location,flashlight,hotspot," + "night,cast"+ (enableNFC ? ",nfc" : ",") + ",inversion"+ (enableAlexa ? ",alexa" : ",") + ",TctRotation,audioEffect" + (enableBatter ? ",battery" : ""); return defaultTiles; } public QSTilecreateTile(String tileSpec) { IQuickSettingsPlugin quickSettingsPlugin = PluginManager .getQuickSettingsPlugin(mContext); boolean nfcQSPanel = mContext.getResources().getBoolean( R.bool.feature_systemui_nfc_support); if (tileSpec.equals("wifi")) return new WifiTile(this); else if (tileSpec.equals("bt")) return new BluetoothTile(this); else if (tileSpec.equals("cell")) return new CellularTile(this); else if (tileSpec.equals("dnd")) return new DndTile(this); else if (tileSpec.equals("inversion")) return new ColorInversionTile(this); else if (tileSpec.equals("airplane")) return new AirplaneModeTile(this); else if (tileSpec.equals("work")) return new WorkModeTile(this);// 不显示 else if (tileSpec.equals("rotation")) return new RotationLockTile(this); else if (tileSpec.equals("flashlight")) return new FlashlightTile(this); else if (tileSpec.equals("location")) return new LocationTile(this); else if (tileSpec.equals("cast")) return new CastTile(this); else if (tileSpec.equals("hotspot")) return new HotspotTile(this); else if (tileSpec.equals("user")) return new UserTile(this);// 不显示 else if (tileSpec.equals("nfc") && nfcQSPanel) return new NfcTile(this); else if (tileSpec.equals("battery")) return new BatteryTile(this); else if (tileSpec.equals("saver")) return new DataSaverTile(this); else if (tileSpec.equals("ring")) return new RingTile(this); else if (tileSpec.equals("screenshot")) return new ScreenShotTile(this); else if (tileSpec.equals("audioEffect")) return new AudioEffectTile(this); else if (tileSpec.equals("alexa") && mContext.getResources().getBoolean( com.android.internal.R.bool.def_tctfw_alexa_enable)) return new AlexaTile(this); else if (tileSpec.equals("TctRotation")) return new TctRotationTile(this); else if (tileSpec.equals(NightModeTile.NIGHT_MODE_SPEC)) return new NightModeTile(this); else if (tileSpec.equals("hotknot") && SIMHelper.isMtkHotKnotSupport()) return new HotKnotTile(this); else if (tileSpec.equals("dataconnection") && !SIMHelper.isWifiOnlyDevice()) return new MobileDataTile(this); else if (tileSpec.equals("simdataconnection") && !SIMHelper.isWifiOnlyDevice() && quickSettingsPlugin .customizeAddQSTile(new SimDataConnectionTile(this)) != null) { return (SimDataConnectionTile) quickSettingsPlugin .customizeAddQSTile(new SimDataConnectionTile(this)); } else if (tileSpec.equals("dulsimsettings") && !SIMHelper.isWifiOnlyDevice() && quickSettingsPlugin .customizeAddQSTile(new DualSimSettingsTile(this)) != null) { return (DualSimSettingsTile) quickSettingsPlugin .customizeAddQSTile(new DualSimSettingsTile(this)); } else if (tileSpec.equals("apnsettings") && !SIMHelper.isWifiOnlyDevice() && quickSettingsPlugin.customizeAddQSTile(new ApnSettingsTile( this)) != null) { return (ApnSettingsTile) quickSettingsPlugin .customizeAddQSTile(new ApnSettingsTile(this)); } else if (quickSettingsPlugin.doOperatorSupportTile(tileSpec)) { // WifiCalling return (QSTile) quickSettingsPlugin.createTile(this, tileSpec); } else if (tileSpec.startsWith(IntentTile.PREFIX)) return IntentTile.create(this, tileSpec); else if (tileSpec.startsWith(CustomTile.PREFIX)) return CustomTile.create(this, tileSpec); else if (mQuickSettingsPlugin.doOperatorSupportTile(tileSpec)) { return (QSTile) mQuickSettingsPlugin.createTile(this, tileSpec); } else { Log.w(TAG, "Bad tile spec: " + tileSpec); return null; } } QSPanel.java @Override public void onTilesChanged() { setTiles(mHost.getTiles()); } public void setTiles(Collection> tiles) { setTiles(tiles, false); } /** * collapsedView = false 展开显示全部快捷键 * collapsedView = true 收起 显示5个快捷键 */ public void setTiles(Collection> tiles, boolean collapsedView) { for (TileRecord record : mRecords) { mTileLayout.removeTile(record); record.tile.removeCallback(record.callback); } mRecords.clear(); for (QSTiletile : tiles) { addTile(tile, collapsedView); } } protected void addTile(final QSTiletile, boolean collapsedView) { final TileRecord r = new TileRecord(); tile.setQSpanel(this); r.tile = tile; r.tileView = createTileView(tile, collapsedView);//创建快捷键图标view …....... r.tile.addCallback(callback); r.callback = callback; //每个title添加点击事件 final View.OnClickListener click = new View.OnClickListener() { @Override public void onClick(View v) { onTileClick(r.tile); } }; //每个title添加长按事件 final View.OnLongClickListener longClick = new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { r.tile.longClick(); return true; } }; //为每个快捷键添加点击+长按 r.tileView.init(click, longClick); r.tile.refreshState(); //将创建的快捷键实例添加到容器mRecords mRecords.add(r); //将刚创建的快捷键添加到可滑动页面板区,即可显示在下拉通知栏中 if (mTileLayout != null) { mTileLayout.addTile(r); } } 

SystemUI 下拉通知栏快捷键加载流程相关推荐

  1. SystemUI之状态栏notification icon加载流程

    2019独角兽企业重金招聘Python工程师标准>>> 引言 今天我们主要讲的是SystemUI状态栏里面另一个常见的icons--notification icons,该icons ...

  2. Vue下拉框动态加载数据

    Vue下拉框动态加载数据 <template><a-select v-model="model.type" show-search placeholder=&qu ...

  3. el-select下拉框懒加载以及搜索联合处理+搜索防抖处理

    前言 本文采主要用了自定义指令结合绑定滚动条事件的方式 问题描述 现有一个页面,充斥着大量表单元素,首先要知道的是vue对于视图上的更新机制,在一个组件内若有元素发生变动,那么整个组件就会刷新渲染,所 ...

  4. dvm,art模式下的dex文件加载流程

    dvm,art模式下的dex文件加载流程 dex加载是学习android的重中之重,刚看完几篇参考博客,对应android源码,收益匪浅,用一篇博客总结一下自己学到的东西. 1.dvm模式下的dex加 ...

  5. android 下拉刷新数据,如何剥离Android页面下拉刷新、加载下一页等逻辑?

    最近碰到一个新的页面控制需求:下拉刷新如果失败,listview上面的数据需要保留,然后悲剧的发现之前写的NetFragment和ListNetFragment都不能覆盖这种逻辑,又要重写了.痛定思痛 ...

  6. 微信小程序实战篇-下拉刷新与加载更多

    下拉刷新 实现下拉刷新目前能想到的有两种方式 调用系统的API,系统有提供下拉刷新的API接口 下拉刷新API.png 监听scroll-view,自定义下拉刷新,还记得scroll-view里面有一 ...

  7. DCloud-MUI 下拉刷新与加载更多

    下拉刷新 单WebView 实现原理 下拉刷新,触发的是原生下拉刷新控件,而整个webview位置不会发生变化,所以不会在拖动过程中发生DOM重绘,当控件拖动到一定位置触发动态加载数据以及刷新操作.此 ...

  8. 小程序 下拉刷新数据加载完毕时停止loading效果

    1.在加载数据函数里加cb 方便回调 2.在数据加载完成时(complete)用 cb && cb()来判断是否有回调函数,如果有则调用. 3.在触发上拉刷新时,在调用加载数据的函数里 ...

  9. 好快, 1分钟写好下拉刷新,滚动加载自动分页列表

    前言 欢迎关注BUI Webapp专栏 或者 bui神速微信公众号. 以往文章: 2019开发最快的Webapp框架--BUI交互框架 微信Webapp开发的各种变态路由需求及解决办法! [BUI实战 ...

最新文章

  1. AngularJS 指令实践
  2. conda 安装软件
  3. 系统架构设计师软考考后回顾
  4. 直播预告 | 腾讯千帆区块链云市场发布会震撼来袭
  5. 罗永浩:6亿债务,已还了4个亿;Python 3.9指日可待|极客头条
  6. 华三ASPF技术白皮书
  7. Swift 网络请求Moya框架简单二次封装
  8. python实现千牛客服自动回复语_千牛旺旺客服设置自动回复的技巧有哪些?总结性文章来啦...
  9. jsp免费虚拟空间 jhost邀请码
  10. Tableau阈值设置及其使用
  11. C语言--指向指针的指针
  12. 如何才能使其输入/输出的参数个数不限
  13. 新监管新纪元 大浪淘沙始见金——“9·4”政策回顾·行业前瞻
  14. AI矩形描边内外同时设置,居中对齐
  15. 深入理解Java虚拟机(周志明版)总结—WSYW126
  16. 今日新闻简报 2020-12-28 每日精选12条新闻简讯
  17. python天天向上的力量三天打鱼两天晒网_三天打鱼两天晒网问题
  18. 用计算机打元宵节快乐,元宵节快乐祝福短语
  19. tf.reduce_mean()
  20. 网页素材大宝库:40套高质量的网站纹理背景素材

热门文章

  1. 4米乘以12米CAD图_简单四步,教你如何绘制好施工现场总平面布置图
  2. ChatGPT评未来考研最好就业的十大专业。你的上榜了吗?
  3. springboot在线订餐系统、
  4. 升级sp3后出现一个问题阻止windows正确检测此机器许可证解决方案
  5. Node进阶——之事无巨细手写Koa源码
  6. 博士申请 | 香港科技大学冯雁教授招收2023秋季入学全奖博士研究生
  7. iOS 修改BundleID后报错
  8. 联想指纹识别程序报错处理
  9. 多摄像机网络智能视频监控系统设计与实现
  10. 【技术分享】Android应用安全开发之浅谈加密算法的坑