Androidの開発は非常に大きな要約記事をお勧めします:お気に入りへようこそ
非常にアンドロイドをお勧めプログラマ、Androidの開発者は、必要不可欠なスキルを必要とします
この資料に記載されているAndroid
この記事を読んで知識の開発の一部を、次のことを刈り取ります。
開始1.DisplayManagerService
2.DisplayManagerService役割
3.DisplayManagerService継承
のコンストラクタ4.DisplayManagerService
ONSTART方法の5.DisplayManagerService
onBootPhase(INT相)方法の6.DisplayManagerServiceを
はじめに
、後続のコードを含む、コードのクラスパスとここでは、以下のディレクトリを参照してください。
frameworks\base\services\java\com\android\server\SystemServer.java
frameworks\base\services\core\java\com\android\server\display\DisplayManagerService.java
1.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のコンポーネントのセットは、表示システムであり、依存する、表示装置を回収し、アダプタの物理的な効果をもたらすことが見出されました。
用のアダプタを使用する2つの方法があります
ローカル表示装置の提供アダプター。
第二に、シミュレーションは、ディスプレイアダプタを開発者に提供します。
DisplayAdapterとDisplayManagerService弱い結合関係。DisplayAdapter
登録することによりDisplayManagerService
、クラスDisplayAdapter.Listener非同期通信を。
そうするには二つの理由がある
巧みな機能のこれら2つのクラスをカプセル化するには、
DisplayAdapter:各表示装置の処理
DisplayManagerServiceグローバル表示状態を処理します:
第二に、非同期表示装置の発見の可能性を排除するデッドロックにつながりました
同期(ゲンロック)
ディスプレイマネージャが複数のスレッドによってアクセスすることができるので、同期ロックので、少し複雑になります。場合は特にウィンドウマネージャ(window manager
)ドロートランザクションコールディスプレイマネージャを(維持しながらdisplay manager
)、ウィンドウマネージャは、それがすぐに適用され、変更することを期待しています。残念ながら、ディスプレイマネージャは、( display manager
)非同期にすべてを行うことはできません。
この問題を解決するために、すべてのオブジェクトマネージャを示すことは同じロックを保持しなければなりません。私たちは、それがユニークなこのロック同期ロックと呼ばれます。
3.DisplayManagerServiceの継承
DisplayManagerService
継承されてSystemService
からSystemServer
スタート。
public final class DisplayManagerService extends SystemService {
...
}
エコプリンティングは、(onBootPhase(int型、コンストラクタ、ONSTART()は、次の方法のライフサイクルを書き換えるためにそれを使用して、基本クラスのシステム・サービスおよび関連するカテゴリである ))、 およびすべてのライフサイクル本土の方法があることができsystem server
、メインスレッド・サイクル・コール。
施工方法
、システムの初期化中にはSystemService
、時間と呼ばれています。
ONSTART()メソッドの
Services
実行時間が呼び出され、今回は発表するために必要なBinder
インタフェース
publishBinderService(文字列、IBinderに)メソッドを
、時には同時にローカルサービスを発表しましたpublishLocalService
共同システムが呼び出しを処理します。
onBootPhase(int)メソッド
まで、スタートアップ段階では、複数回呼び出されるPHASE_BOOT_COMPLETED
以下のDisplayManagerService
使用方法が来て、このプロセスに従ったものです。
4.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();
}
ONSTARTの5.DisplayManagerService方法
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;
...
}
。registerDefaultDisplayAdapters
以下の方法である:
registerDefaultDisplayAdapters
主な機能が追加表示装置に登録することであるmDisplayAdapters
アダプタを。
private void registerDefaultDisplayAdapters() {
// Register default display adapters.
synchronized (mSyncRoot) {
// b. 主要的显示适配器,注册本地适配器lock
registerDisplayAdapterLocked(new LocalDisplayAdapter(
mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
...
}
B。メインディスプレイアダプタ、アダプタロックローカル登録 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, activeConfig,
colorModes, 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
、及びアプリオープン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);
}
onBootPhase(INT相)法の6.DisplayManagerService
@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) {
}
}
}
}
}
間違った場所、あなたの提案や修正を歓迎している場合これまでのところ、本明細書に、これは、終了しました。同時に、あなたの注意を楽しみにして、お読みいただきありがとうございました、ありがとうございました!