极力推荐AndroID 开发大总结文章:欢迎收藏
程序员Android 力荐 ,Android 开发者需要的必备技能
本篇文章主要介绍 AndroID
开发中的部分知识点,通过阅读本篇文章,您将收获以下内容:
1.displayManagerService的启动
2.displayManagerService 作用
3.displayManagerService 继承关系
4.displayManagerService 的构造方法
5.displayManagerService 的onStart 方法
6.displayManagerService 的onBootPhase(int phase) 方法
前言
本文涉及代码类路径如下,后续涉及代码内容,请参考以下目录。
frameworks\base\services\java\com\androID\server\SystemServer.javaframeworks\base\services\core\java\com\androID\server\display\displayManagerService.java1.displayManagerService的启动
displayManagerService 是有 SystemServer
在startbootstrapServices
引导阶段中通过startService
启动,代码如下:
public final class SystemServer { ... private voID startbootstrapServices() { ... // display manager is needed to provIDe display metrics before package manager // starts up. traceBeginAndSlog("StartdisplayManager"); //1.启动 displayManagerService mdisplayManagerService = mSystemServiceManager.startService(displayManagerService.class); traceEnd(); ... } ...}2.displayManagerService 作用
displayManagerService 用来管理显示的生命周期,它决定如何根据当前连接的物理显示设备控制其逻辑显示,并且在状态更改时,向系统和应用程序发送通知,等等。
displayAdapter 是 displayManagerService 所依赖的集合组件,其为系统显示,收集并发现物理显示设备提供了适配器的作用。
目前有以下两种方式的适配器供使用
一、为本地显示设备提供适配器。
二、为开发者提供的模拟显示适配器。
displayAdapter 与 displayManagerService 是弱耦合关系。displayAdapter
通过注册在 displayManagerService
类中的 displayAdapter.Listener 实现异步通信。
这样做有两个原因
一、巧妙地封装了这两个类的职责,
displayAdapter :处理各个显示设备
displayManagerService:处理全局显示状态。
二、消除异步显示设备发现导致死锁的可能性
Synchronization(同步锁)
因为显示管理器可能被多个线程访问,所以同步锁就会变得有点复杂。 特别是当窗口管理器(window manager
)在保持绘制事务的同时调用显示管理器(display manager
),窗口管理器期望它可以立即应用并更改。 但不幸的是,显示管理器(display manager
)不能异步地做所有事情。
为了解决这个问题,显示管理器的所有对象必须持有相同的锁。 我们将此锁称为同步锁,它具有唯一性。
displayManagerService
继承 SystemService
,由 SystemServer
启动。
public final class displayManagerService extends SystemService { ... }
SystemService 是系统Service的基类,相关类使用要重写它的以下生命周期方法(构造方法、onStart() 、onBootPhase(int)),并且所有生命周期内地方法都可以被 system server
主线程循环调用。
构造方法
在系统 初始化SystemService
的时候被调用。
onStart()方法Services
运行时候被调用,并且此时需要对外公布Binder
接口
publishBinderService(String,IBinder)方法
有时候会同时对外公布本地服务publishLocalService
共系统进程调用。
onBootPhase(int)方法
在启动阶段会被调用多次,一直到PHASE_BOOT_COMPLETED
下面displayManagerService
的使用方法也是按照这个流程来的。
displayManagerService
构造方法代码如下:
public displayManagerService(Context context) { this(context,new Injector()); } @VisibleForTesting displayManagerService(Context context,Injector injector) { super(context); mInjector = injector; mContext = context; // mHandler 用来发送 display 消息 mHandler = new displayManagerHandler(displayThread.get().getLooper()); mUiHandler = UiThread.getHandler(); mdisplayAdapterListener = new displayAdapterListener(); mSingledisplayDemoMode = SystemPropertIEs.getBoolean("persist.demo.singledisplay",false); mDefaultdisplayDefaultcolorMode = mContext.getResources().getInteger( com.androID.internal.R.integer.config_defaultdisplayDefaultcolorMode); PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mGlobaldisplayBrightness = pm.getDefaultScreenBrightnessSetting(); }5.displayManagerService 的onStart 方法
onStart 主要加载持久化数据(主要是显示设备的宽高等),发送 MSG_REGISTER_DEFAulT_disPLAY_ADAPTERS
消息,对外公布Binder、Local Service
等。onStart()
方法如下:
@OverrIDe public voID onStart() { // We need to pre-load the persistent data store so it's ready before the default display // adapter is up so that we have it's configuration. We Could load it lazily,but since // we're going to have to read it in eventually we may as well do it here rather than after // we've waited for the display to register itself with us. synchronized(mSyncRoot) { //1. 加载本地持久化数据 mPersistentDataStore.loadIfNeeded(); loadStabledisplayValuesLocked(); } // 2. 发送MSG_REGISTER_DEFAulT_disPLAY_ADAPTERS 消息 mHandler.sendEmptyMessage(MSG_REGISTER_DEFAulT_disPLAY_ADAPTERS); //3.对外公布Binder、Local 服务 publishBinderService(Context.disPLAY_SERVICE,new BinderService(),true /*allowIsolated*/); publishLocalService(displayManagerInternal.class,new LocalService()); publishLocalService(displaytransformManager.class,new displaytransformManager()); }加载本地持久化数据
private voID loadIfNeeded() { if (!mloaded) { load(); mloaded = true; } } private voID load() { clearState(); final inputStream is; try { is = mAtomicfile.openRead(); } catch (fileNotFoundException ex) { return; } XmlPullParser parser; try { parser = Xml.newPullParser(); parser.setinput(new BufferedinputStream(is),StandardCharsets.UTF_8.name()); loadFromXml(parser); } catch (IOException | XmlPullParserException ex) { Slog.w(TAG,"Failed to load tv input manager persistent store data.",ex); clearState(); } finally { IoUtils.closeQuIEtly(is); } }
2.MSG_REGISTER_DEFAulT_disPLAY_ADAPTERS
消息 处理方法如下:
private final class displayManagerHandler extends Handler { public displayManagerHandler(Looper looper) { super(looper,null,true /*async*/); } @OverrIDe public voID handleMessage(Message msg) { switch (msg.what) { case MSG_REGISTER_DEFAulT_disPLAY_ADAPTERS: // a.注册默认的显示适配器 registerDefaultdisplayAdapters(); break; case MSG_REGISTER_ADDITIONAL_disPLAY_ADAPTERS: registeradditionaldisplayAdapters(); break; ... }
a.registerDefaultdisplayAdapters
实现方法如下:registerDefaultdisplayAdapters
最主要功能就是将显示设备添加注册到mdisplayAdapters
适配器中。
private voID registerDefaultdisplayAdapters() { // Register default display adapters. synchronized (mSyncRoot) { // b. 主要的显示适配器,注册本地适配器lock registerdisplayAdapterLocked(new LocaldisplayAdapter( mSyncRoot,mContext,mHandler,mdisplayAdapterListener)); ... }
b. 主要的显示适配器,注册本地适配器lock registerdisplayAdapterLocked
private voID registerdisplayAdapterLocked(displayAdapter adapter) { mdisplayAdapters.add(adapter); adapter.registerLocked(); }
LocaldisplayAdapter 继承 displayAdapter ,主要为本地显示设备提供的适配器。
final class LocaldisplayAdapter extends displayAdapter { ... // Called with SyncRoot lock held. public LocaldisplayAdapter(displayManagerService.SyncRoot syncRoot,Context context,Handler handler,Listener Listener) { super(syncRoot,context,handler,Listener,TAG); } // registerdisplayAdapterLocked 中 调用 adapter.registerLocked(); @OverrIDe public voID registerLocked() { super.registerLocked(); // 1.创建显示设备热插拔时间的监听器 mHotplugReceiver = new HotplugdisplayEventReceiver(getHandler().getLooper()); for (int builtIndisplayID : BUILT_IN_disPLAY_IDS_TO_SCAN) { //2.连接显示设备 tryConnectdisplayLocked(builtIndisplayID); } } ...}
1.创建显示设备热插拔时间的监听器,部分代码如下:
private final class HotplugdisplayEventReceiver extends displayEventReceiver { public HotplugdisplayEventReceiver(Looper looper) { super(looper,VSYNC_SOURCE_APP); } @OverrIDe public voID onHotplug(long timestampNanos,int builtIndisplayID,boolean connected) { synchronized (getSyncRoot()) { if (connected) { //连接显示设备 tryConnectdisplayLocked(builtIndisplayID); } else { trydisconnectdisplayLocked(builtIndisplayID); } } } }
2.连接显示设备,部分代码如下:
private voID tryConnectdisplayLocked(int builtIndisplayID) { IBinder displayToken = SurfaceControl.getBuiltIndisplay(builtIndisplayID); if (displayToken != null) { SurfaceControl.PhysicaldisplayInfo[] configs = SurfaceControl.getdisplayConfigs(displayToken); int activeConfig = SurfaceControl.getActiveConfig(displayToken); int activecolorMode = SurfaceControl.getActivecolorMode(displayToken); int[] colorModes = SurfaceControl.getdisplaycolorModes(displayToken); LocaldisplayDevice device = mDevices.get(builtIndisplayID); if (device == null) { // display was added. device = new LocaldisplayDevice(displayToken,builtIndisplayID,configs,activeConfig,colorModes,activecolorMode); mDevices.put(builtIndisplayID,device); senddisplayDeviceEventLocked(device,disPLAY_DEVICE_EVENT_ADDED); } else if (device.updatePhysicaldisplayInfolocked(configs,activecolorMode)) { // display propertIEs changed. senddisplayDeviceEventLocked(device,disPLAY_DEVICE_EVENT_CHANGED); } } else { // The display is no longer available. Ignore the attempt to add it. // If it was connected but has already been disconnected,we'll get a // disconnect event that will remove it from mDevices. } }
然后对 其他services
以及app 公开publishBinderService
接口
/** * Publish the service so it is accessible to other services and apps. */ protected final voID publishBinderService(String name,IBinder service,boolean allowIsolated) { ServiceManager.addService(name,service,allowIsolated); }
然后对 系统进程 公开publishLocalService
接口
/** * Publish the service so it is only accessible to the system process. */ protected final <T> voID publishLocalService(Class<T> type,T service) { LocalServices.addService(type,service); }6.displayManagerService 的onBootPhase(int phase) 方法
@OverrIDe public voID onBootPhase(int phase) { if (phase == PHASE_WAIT_FOR_DEFAulT_disPLAY) { synchronized (mSyncRoot) { long timeout = SystemClock.uptimeMillis() + mInjector. (); while (mLogicaldisplays.get(display.DEFAulT_disPLAY) == null || mVirtualdisplayAdapter == null) { long delay = timeout - SystemClock.uptimeMillis(); if (delay <= 0) { throw new RuntimeException("Timeout waiting for default display " + "to be initialized. Defaultdisplay=" + mLogicaldisplays.get(display.DEFAulT_disPLAY) + ",mVirtualdisplayAdapter=" + mVirtualdisplayAdapter); } if (DEBUG) { Slog.d(TAG,"waitForDefaultdisplay: waiting,timeout=" + delay); } try { mSyncRoot.wait(delay); } catch (InterruptedException ex) { } } } } }
至此,本篇已结束,如有不对的地方,欢迎您的建议与指正。同时期待您的关注,感谢您的阅读,谢谢!
总结以上是内存溢出为你收集整理的DisplayManagerService(一)全部内容,希望文章能够帮你解决DisplayManagerService(一)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)