[Android]アクティビティウィンドウのWMSソースコードの関係プロセス

1.クラス図の関係

system_server_AMSクラス
ここに画像の説明を挿入
_1:Activity_Window_関連クラス図:
ここに画像の説明を挿入
system_server_AMSクラス_2:
ここに画像の説明を挿入
全体的なクラス図:
ここに画像の説明を挿入

フローチャート:
ここに画像の説明を挿入

2.関連する概念

1. ActivityThread:アプリケーションのメインスレッドクラスです。すべてのAPKプログラムには1つのActivityThreadしかありません。プログラムのエントリは、このクラスの静的main()関数です
。Activity:アクティビティには、アクティビティのattachメソッドにあるウィンドウが含まれていますnew PhoneWindow();を呼び出してウィンドウを作成します
。2。PhoneWindow:Windowクラスを継承し、FrameLayoutをある程度ラップし、DecorView
3 を含む一般的なウィンドウ操作インターフェイスのセットを提供します。ビュー:最も基本的なUI画面上の長方形の領域を表すコンポーネント;
4. DecorView:このクラスはFrameLayoutのサブクラスであり、PhoneWindowの内部クラスです。英語の装飾は装飾であり、これは「装飾」を意味します。DecorViewは、一般的なタイトルバーの追加や特定のキーメッセージへの応答など、通常のFrameLayoutを変更します。;
5.ウィンドウ:トップレベルウィンドウ、管理インターフェイスの表示、イベントへの応答を表します。各アクティビティは、アクティビティとビューシステム全体の間のインターフェイスであるPhoneWindowオブジェクトを作成します。このクラスは、一連の共通ウィンドウ(ウィンドウ)を提供しますAPIを操作する場合、ここでのウィンドウはプログラムレベルのみです。WMSによって管理されるウィンドウはWindowクラスではなく、一般にDecorViewクラスを参照するViewまたはViewGroupクラスです。つまり、DecorViewはWmSによって管理されるウィンドウです。ウィンドウは抽象型です。
6、WindowManager:ViewManagerから継承されたインターフェイス。アプリケーションプロセスのウィンドウマネージャー。実装にはWindowManagerImplがあり、
主に、状態、属性、ビューの追加、削除、更新、ウィンドウの順序、メッセージの収集、およびウィンドウの処理を管理するために使用されます。
7. ViewRootImpl:IWindowSessionインターフェイスを介してグローバルウィンドウマネージャーとやり取りします。インターフェイスコントロールとメッセージレスポンスです。WMSがクライアントウィンドウを管理している場合、非同期メッセージを介して行われる特定の操作をクライアントに通知する必要があります。

3、ステップ

ステップ1:
アクティビティが開始されると、system_serverプロセスは、AMS(ActivityManagerService)リモートエージェントApplicationThreadProxy(つまり、アプリケーションプロセスのバインダー、IApplicationThread)のscheduleLaunchActivit()を渡し、SCHEDULE_LAUNCH_ACTIVITY_TRANSACTIONをマークし、基になるバインダードライバーは、アプリケーションプロセスXXXActivityをアプリケーションのActivityThreadの内部に開始します。クラスApplicationThreadの親クラスApplicationNativeのonTransact、次にscheduleLaunchActivity()への
ステップ2:
ApplicationThreadのscheduleLaunchActivity:sendMessage(H.LAUNCH_ACTIVITY、r)を通じて、UIスレッドに送信されるActivityThreadのH処理は、handleLaunchActivity:
ActivityThread.java:です。

public final class ActivityThread {
    
    
      private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    
    
        // Initialize before creating the activity
        WindowManagerGlobal.initialize();
        Activity a = performLaunchActivity(r, customIntent);
        if (a != null) {
    
    
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
        ...
        } 
    }
}

その中で、WindowManagerGlobal.initialize;は、最初にWMS(WindowManagerService)をフェッチするリモートエージェントIWindowManagerです。

WindowManagerGlobal.java:

public final class WindowManagerGlobal {
    
    
    public static void initialize() {
    
    
        getWindowManagerService();
    }
    public static IWindowManager getWindowManagerService() {
    
    
        synchronized (WindowManagerGlobal.class) {
    
    
            if (sWindowManagerService == null) {
    
    
                sWindowManagerService = IWindowManager.Stub.asInterface(
                        ServiceManager.getService("window"));
                try {
    
    
                    sWindowManagerService = getWindowManagerService();
                    ValueAnimator.setDurationScale(sWindowManagerService.getCurrentAnimatorScale());
                } catch (RemoteException e) {
    
    
                    throw e.rethrowFromSystemServer();
                }
            }
            return sWindowManagerService;
        }
    }
}

Activity a = performLaunchActivity(r、customIntent); ClassLoaderを使用してXXXActivityをロードします。これにより、ContextImplが作成されます。アプリケーションが開始されていない場合は、最初にApplicaitionとonCreateが作成され、次にXXXActivity attach();が呼び出され
ます。 PhoneWindowであるアクティビティの対応するウィンドウと、phoneWindowとWindowManagerImplの間の関連付けを変更します

final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window) {
    
    
        attachBaseContext(context);
        mFragments.attachHost(null /*parent*/);
        mWindow = new PhoneWindow(this, window);
        mWindow.setWindowControllerCallback(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
        mMainThread = aThread;
        mInstrumentation = instr;
        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        if (mParent != null) {
    
    
            mWindow.setContainer(mParent.getWindow());
        }
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;
}

それらの中で:(WindowManager)context.getSystemService(Context.WINDOW_SERVICE)はWindowManagerImplを取得します:
ここでContextImpl.getSystemServiceに移動します:

class ContextImpl extends Context {
    
       
  @Override
    public Object getSystemService(String name) {
    
    
        return SystemServiceRegistry.getSystemService(this, name);
    }
}

SystemServiceRegistry:

final class SystemServiceRegistry {
    
    
  public static Object getSystemService(ContextImpl ctx, String name) {
    
    
        ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
        return fetcher != null ? fetcher.getService(ctx) : null;
    }
  private static final HashMap<Class<?>, String> SYSTEM_SERVICE_NAMES =
            new HashMap<Class<?>, String>();
    private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
            new HashMap<String, ServiceFetcher<?>>();
    private static int sServiceCacheSize;
    static {
    
    
        registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
                new CachedServiceFetcher<AccessibilityManager>() {
    
    
            @Override
            public AccessibilityManager createService(ContextImpl ctx) {
    
    
                return AccessibilityManager.getInstance(ctx);
            }});
    registerService(Context.WINDOW_SERVICE, WindowManager.class,
                new CachedServiceFetcher<WindowManager>() {
    
    
            @Override
            public WindowManager createService(ContextImpl ctx) {
    
    
                return new WindowManagerImpl(ctx);
            }});
}

戻り値は新しいWindowManagerImpl(ctx);です。performLaunchActivity関数では、アタッチ後、mInstrumentation.callActivityOnCreateの呼び出しを続行して、XXXActivityのonCreateを実装します。このとき、全員がsetContentView(R.layout.xxx)
Step3:
Activity.setContentView()を書き込みます
PhoneWindowクラスのsetContentViewであるgetWindow()。setContentView(layoutResID)を呼び出します:PhoneWindowで主にDecorView mDecor(これはウィンドウの装飾を含むウィンドウのトップレベルのビューです)を作成し、mDecorからandroidを検索します。 R.id.content:mContentParent(ViewGroup)、アクティビティによって設定されたビューをmContentParent.addView(view、params);に追加します。

public void setContentView(@LayoutRes int layoutResID) {
    
    
        getWindow().setContentView(layoutResID);
        initWindowDecorActionBar();
}

PhoneWindow:

public class PhoneWindow extends Window implements MenuBuilder.Callback {
    
    
  public void setContentView(int layoutResID) {
    
    
        
        if (mContentParent == null) {
    
    
            installDecor();
        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
    
    
            mContentParent.removeAllViews();
        }

        if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
    
    
            final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
                    getContext());
            transitionTo(newScene);
        } else {
    
    
            mLayoutInflater.inflate(layoutResID, mContentParent);
        }
        mContentParent.requestApplyInsets();
        final Callback cb = getCallback();
        if (cb != null && !isDestroyed()) {
    
    
            cb.onContentChanged();
        }
        mContentParentExplicitlySet = true;
    }
}

ステップ4:
ActivitThread.handleLaunchActivity関数がperformLaunchActivityを完了した後、handleResumeActivity関数に移動し、start r = performResumeActivity(token、clearHide、reason);を表示して、XXXActivityのonResumeに移動します。
次に、ウィンドウタイプがアクティビティの対応するウィンドウに設定されます。** l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION、** WMSはウィンドウで動作し、各アクティビティはウィンドウに対応します。フレームワークは、次のようないくつかのウィンドウタイプを定義します。システムウィンドウ、アプリケーションウィンドウ、子ウィンドウなど ここでのタイプは非常に重要です。これがないと、ウィンドウに表示できません。
次に、ViewManager wm = a.getWindowManager(); wm.addView(decor、l);を呼び出し、WindowManagerImpl.addView:
ActivityThread を呼び出します

final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
    
    
        ActivityClientRecord r = mActivities.get(token);
        ...
        r = performResumeActivity(token, clearHide, reason);
        ...
            if (r.window == null && !a.mFinished && willBeVisible) {
    
    
                r.window = r.activity.getWindow();
                View decor = r.window.getDecorView();
                decor.setVisibility(View.INVISIBLE);
                ViewManager wm = a.getWindowManager();
                WindowManager.LayoutParams l = r.window.getAttributes();
                a.mDecor = decor;
                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                l.softInputMode |= forwardBit;
                if (r.mPreserveWindow) {
    
    
                    a.mWindowAdded = true;
                    r.mPreserveWindow = false;
                   
                    ViewRootImpl impl = decor.getViewRootImpl();
                    if (impl != null) {
    
    
                        impl.notifyChildRebuilt();
                    }
                }
                if (a.mVisibleFromClient && !a.mWindowAdded) {
    
    
                    a.mWindowAdded = true;
                    wm.addView(decor, l);
                }
             ...
    }

ステップ5:
WindowManagerImplのaddViewがWindowManagerGlobal.getInstance()のaddViewに呼び出されます:
この関数はroot = new ViewRootImpl(view.getContext()、display);を作成し、次にmRoots.add(root)に保存して
からroot.setView( view、wparams、panelParentView);

public final class WindowManagerImpl implements WindowManager {
    
    
    private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
    @Override
    public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
    
    
        applyDefaultToken(params);
        mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
    }
}

public final class WindowManagerGlobal {
    
    
    public void addView(View view, ViewGroup.LayoutParams params, Display display, Window parentWindow) {
    
    
        ...
        ViewRootImpl root;
        View panelParentView = null;
        synchronized (mLock) {
    
    
            ...
            root = new ViewRootImpl(view.getContext(), display);
            view.setLayoutParams(wparams);
            mViews.add(view);
            mRoots.add(root);
            mParams.add(wparams);
        }
        // do this last because it fires off messages to start doing things
        try {
    
    
            root.setView(view, wparams, panelParentView);
        } catch (RuntimeException e) {
    
    
           
        }
    }
}

ステップ6:
ViewRootImpl.setView():
この関数では、IWindowSession mWindowSessionおよびリモートWMS SeesionオブジェクトがWindowManagerGloablを通じて取得され、mWindowSession.addToDisplayがsystem_serverプロセスのセッションに対して実行されます。

public final class ViewRootImpl implements ViewParent, View.AttachInfo.Callbacks, ThreadedRenderer.HardwareDrawCallbacks {
    
    
    public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
    
    
        synchronized (this) {
    
    
                ....
                try {
    
    
                    res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
                            getHostVisibility(), mDisplay.getDisplayId(),
                            mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
                            mAttachInfo.mOutsets, mInputChannel);
                }            
            }
        ...
    }
}

このmWindowSessionは

public static IWindowSession getWindowSession() {
    
    
        synchronized (WindowManagerGlobal.class) {
    
    
            if (sWindowSession == null) {
    
    
                try {
    
    
                    InputMethodManager imm = InputMethodManager.getInstance();
                    IWindowManager windowManager = getWindowManagerService();
                    sWindowSession = windowManager.openSession(
                            new IWindowSessionCallback.Stub() {
    
    
                                @Override
                                public void onAnimatorScaleChanged(float scale) {
    
    
                                    ValueAnimator.setDurationScale(scale);
                                }
                            },
                            imm.getClient(), imm.getInputContext());
                } catch (RemoteException e) {
    
    
                    throw e.rethrowFromSystemServer();
                }
            }
            return sWindowSession;
        }
    }

WindowManagerServiceのopenSessionメソッドを呼び出します。

public class WindowManagerService extends IWindowManager.Stub implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
    
    
   @Override
    public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client, IInputContext inputContext) {
    
    
        if (client == null) throw new IllegalArgumentException("null client");
        if (inputContext == null) throw new IllegalArgumentException("null inputContext");
        Session session = new Session(this, callback, client, inputContext);
        return session;
    }
}

おすすめ

転載: blog.csdn.net/sinat_36955332/article/details/108488674