Android SystemUI组件(02)SystemBars分析

阅读: 评论:0

Android SystemUI组件(02)SystemBars分析

Android SystemUI组件(02)SystemBars分析

该系列文章总纲链接:专题分纲目录 Android SystemUI组件


本章关键点总结 & 说明:

说明:本章节持续迭代之前章节的思维导图,主要关注下方 SystemBars分析部分即可。主要解读了SystemBars的启动流程以及如何调用到 状态栏和导航栏的创建函数。

1 SystemBars start 启动分析

分析SystemBars的start方法,代码实现如下:

public class SystemBars extends SystemUI implements ServiceMonitor.Callbacks {//...private ServiceMonitor mServiceMonitor;@Overridepublic void start() {mServiceMonitor = new ServiceMonitor(TAG, DEBUG,mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this);// will call onNoService if no remote service is foundmServiceMonitor.start();  }//...
}

这里继续分析关键代码mServiceMonitor.start()的实现,如下所示:

public class ServiceMonitor {//...public void start() {// listen for setting changesContentResolver cr = ContentResolver();cr.registerContentObserver(UriFor(mSettingKey),false /*notifyForDescendents*/, mSettingObserver, UserHandle.USER_ALL);// listen for package/component changesIntentFilter filter = new IntentFilter();filter.addAction(Intent.ACTION_PACKAGE_ADDED);filter.addAction(Intent.ACTION_PACKAGE_CHANGED);filter.addDataScheme("package");isterReceiver(mBroadcastReceiver, filter);mHandler.sendEmptyMessage(MSG_START_SERVICE);}//...
}

这里最后通过handler发送了消息MSG_START_SERVICE,对于MSG_START_SERVICE的处理代码如下:

private final Handler mHandler = new Handler() {public void handleMessage(Message msg) {switch(msg.what) {case MSG_START_SERVICE:startService();break;case MSG_CONTINUE_START_SERVICE:continueStartService();break;case MSG_STOP_SERVICE:stopService();break;//...}}
};

对消息的处理主要是执行startService方法,实现如下:

private void startService() {mServiceName = getComponentNameFromSetting();if (mServiceName == null) {mBound = false;//这个mCallbacks对象就是之前传入进来的SystemBar类型的NoService();} else {long delay = ServiceStartAttempt();mHandler.sendEmptyMessageDelayed(MSG_CONTINUE_START_SERVICE, delay);}
}

对于第一次启动的服务会走上面的分支,SystemBar的onNoService代码实现如下:

    @Overridepublic void onNoService() {// fallback to using an in-process implementationcreateStatusBarFromConfig();  }

继续分析createStatusBarFromConfig的实现,代码如下所示:

private void createStatusBarFromConfig() {final String clsName = String(fig_statusBarComponent);//...//通过类加载器实例化类Class<?> cls = null;//...cls = ClassLoader().loadClass(clsName);//...mStatusBar = (BaseStatusBar) wInstance();//...mStatusBar.mContext = mContext;mStatusBar.mComponents = mComponents;mStatusBar.start();
}

当远程服务没有启动时,首先从xml文件读取要启动的类名,我们来查看这个xml文件 resl,内容如下:

<resources>...<!-- Component to be used as the status bar service.  Must implement the IStatusBarinterface.  This name is in the ComponentName flattened format (package/class)  --><string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.PhoneStatusBar</string>...
</resources>

由上可知,这个StatusBar实际上是PhoneStatusBar,从这里开始将进入到PhoneStatusBar的启动流程,在这里我们开始探寻导航栏和状态的创建方法的探寻。

2 导航栏创建方法探寻

实例化PhoneStatusBar类后会调用start方法,我们就从PhoneStatusBar的start方法开始分析,start方法代码实现如下:

@Override
public void start() {mDisplay = ((SystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();updateDisplaySize();//src绘图模式mScrimSrcModeEnabled = Resources().getBoolean(fig_status_bar_scrim_behind_use_src);//调用父类BaseStatusBar的start方法super.start(); // calls createAndAddWindows()mMediaSessionManager= (MediaSessionManager) SystemService(Context.MEDIA_SESSION_SERVICE);//创建导航栏addNavigationBar();//更新状态栏图标mIconPolicy = new PhoneStatusBarPolicy(mContext, mCastController, mHotspotController);Change(false); // Change(true); // set upif (ENABLE_HEADS_UP) {ContentResolver().registerContentObserver(UriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED), true,mHeadsUpObserver);ContentResolver().registerContentObserver(UriFor(SETTING_HEADS_UP_TICKER), true,mHeadsUpObserver);}mUnlockMethodCache = Instance(mContext);mUnlockMethodCache.addListener(this);//启动锁屏startKeyguard();mDozeServiceHost = new DozeServiceHost();putComponent(DozeHost.class, mDozeServiceHost);putComponent(PhoneStatusBar.class, this);setControllerUsers();notifyUserAboutHiddenNotifications();mScreenPinningRequest = new ScreenPinningRequest(mContext);
}

这里我们看到了导航栏创建的关键方法:addNavigationBar(),接下来我们继续探寻 状态栏的创建方法。

3 状态栏创建方法探寻

PhoneStatusBar的start方法中调用了父类(BaseStatusBar类型)的start()方法,代码实现如下:

public void start() {//状态栏的窗口需要使用WM进行窗口的创建,因为不属于ActivitymWindowManager = (SystemService(Context.WINDOW_SERVICE);mWindowManagerService = WindowManagerService();mDisplay = DefaultDisplay();mDevicePolicyManager = (SystemService(Context.DEVICE_POLICY_SERVICE);mNotificationColorUtil = Instance(mContext);mNotificationData = new NotificationData(this);mAccessibilityManager = (SystemService(Context.ACCESSIBILITY_SERVICE);mDreamManager = IDreamManager.Stub.asInterface(ServiceManager.checkService(DreamService.DREAM_SERVICE));mPowerManager = (PowerManager) SystemService(Context.POWER_SERVICE);//监听设备归属状态的变化,以禁用或启用某些功能Change(false); // set up//监听设置文件的改变,以便更新ContenProvider数据库ContentResolver().registerContentObserver(UriFor(Settings.Global.DEVICE_PROVISIONED), true,mSettingsObserver);ContentResolver().registerContentObserver(UriFor(Settings.Global.ZEN_MODE), false,mSettingsObserver);ContentResolver().registerContentObserver(UriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS), false,mSettingsObserver,UserHandle.USER_ALL);ContentResolver().registerContentObserver(UriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),true,mLockscreenSettingsObserver,UserHandle.USER_ALL);//获取statusbarService服务,于SystemUI而言是一个代理,它会将操作状态栏的请求发送给SystemUI,并由后者来完成请求。mBarService = IStatusBarService.Stub.Service(Context.STATUS_BAR_SERVICE));//设置recents回调函数mRecents = getComponent(RecentsComponent.class);mRecents.setCallback(this);final Configuration currentConfig = Resources().getConfiguration();mLocale = currentConfig.locale;mLayoutDirection = LayoutDirectionFromLocale(mLocale);mFontScale = currentConfig.fontScale;mUserManager = (UserManager) SystemService(Context.USER_SERVICE);//动画相关mLinearOutSlowIn = AnimationUtils.loadInterpolator(mContext,android.R.interpolator.linear_out_slow_in);mFastOutLinearIn = AnimationUtils.loadInterpolator(mContext,android.R.interpolator.fast_out_linear_in);// Connect in to the status bar manager serviceStatusBarIconList iconList = new StatusBarIconList();mCommandQueue = new CommandQueue(this, iconList);int[] switches = new int[8];ArrayList<IBinder> binders = new ArrayList<IBinder>();//...//经过一系列对象的创建与初始化后,开始向StatusBarService进行注册。isterStatusBar(mCommandQueue, iconList, switches, binders);//...//关键点:创建 状态栏和导航栏窗口。由于创建状态栏和导航栏 窗口涉及到控件树的创建,因此它由子类PhoneStatusBar或TabletStatusBar实现,以根据不同的布局方案选择创建不同的窗口与控件树。createAndAddWindows();/*应用来自IStatusBarService中所获取的信息。mCommandQueue已经注册到IStatusBarService中,状态栏与导航栏的窗口与控件树也都创建完毕。接下来是应用从IStatusBarService中所获取的信息 */disable(switches[0], false /* animate */);// 设置SystemUIVisibilitysetSystemUiVisibility(switches[1], 0xffffffff);// 设置菜单键的可见性topAppWindowChanged(switches[2] != 0);// 根据输入法窗口的可见性调整导航栏的样式(0), switches[3], switches[4], switches[5] != 0);// 依次向系统状态区添加状态图标int N = iconList.size();int viewIndex = 0;for (int i=0; i<N; i++) {StatusBarIcon icon = Icon(i);if (icon != null) {Slot(i), i, viewIndex, icon);viewIndex++;}}// Set up the initial notification state.//...isterAsSystemService(mContext,new PackageName(), getClass().getCanonicalName()),UserHandle.USER_ALL);//...mCurrentUserId = CurrentUser();setHeadsUpUser(mCurrentUserId);IntentFilter filter = new IntentFilter();filter.addAction(Intent.ACTION_USER_SWITCHED);filter.addAction(Intent.ACTION_USER_ADDED);filter.addAction(BANNER_ACTION_CANCEL);filter.addAction(BANNER_ACTION_SETUP);filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);isterReceiver(mBroadcastReceiver, filter);updateCurrentProfilesCache();
}

BaseStatusBar.start()函数中最主要的是调用createAndAddWindows方法,我们看下这个方法的定义,如下:

/*** Create all windows necessary for the status bar (including navigation, overlay panels, etc)* and add them to the window manager.*/
protected abstract void createAndAddWindows();

最后还是调用回子类PhoneStatusBar中的createAndAddWindows,代码实现如下:

@Override
public void createAndAddWindows() {addStatusBarWindow();
}

致此,经过前面的分析,我们了解到,通过SystemBars的start启动,最终执行到了两个关键函数:

  • addNavigationBar(); //创建导航栏(PhoneStatusbar)
  • addStatusBarWindow();//创建状态栏(BaseStatusbar)

下一章节开始,我们从创建流程开始分析 状态栏和导航栏。

本文发布于:2024-02-05 05:08:37,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170724863963314.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:组件   SystemUI   Android   SystemBars
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23