android(three)、アクティビティの動作原理

新しいアプリケーションが開始されると、最初にstartActivityが呼び出されてアクティビティが開始されます。この時点では、プロセスはまだ作成されておらず、新しいプロセスがフォークされ、ActivityThreadのインスタンスが作成されます。


アクティビティ作成プロセス


   Androidのアクティビティは、ユーザー操作とビューの間のメッセージ転送を担当する単なるコントローラーです。アクティビティは、ユーザーがUIを配置できるようにするウィンドウ(setContentView)インスタンスを作成しますが、ビュー自体ではなく、UIでの操作も行いません。

   ウィンドウはトップレベルのウィンドウクラスです。パフォーマンス戦略として、通常はビューとしてウィンドウマネージャーに追加されます。各アクティビティインスタンスはウィンドウインスタンスに対応します。Windowは単なる抽象クラスであり、その実装クラスはandroid.policy.PhoneWindowであり、これは非常に重要なクラスです。

  通常、アクティビティを開始すると、startActivity()メソッドが呼び出されます。startActivityメソッドは、インストルメンテーションと呼ばれるクラスを介して内部的に呼び出され、アクティビティが開始されます。

  インストルメンテーションは、アプリケーション管理活動のためのツールクラスです。これは、活動の完全なライフサイクルを制御する方法を提供する。アプリケーションが作成されると、それは最初に作成されます計装インスタンスを、および計装はexecStartActivitiesを呼び出すことにより、活動を開始します 

 アクティビティの作成手順は次のとおりです。

   ステップ1:作成情報をInstrumentation byContextに送信します。
   2番目のステップ:インストルメンテーションは、情報をActivityManagerServiceに転送します。
   3番目のステップ:ActivityManagerServiceは、Activityの関連する記録作業を完了した、作成情報をApplicationThreadに送信します。
   4番目の部分:ActivityThreadは(Instrumentation)アクティビティ作成メソッドを呼び出し、アクティビティのライフサイクルを実行します。

 上記の4つの部分は、フレームワークとアプリケーション間の簡略化された情報転送プロセスであり、実際の操作は非常に複雑になります。


  execStartActivitiesのメソッド本体は次のとおりです

 public void execStartActivities(Context who, IBinder contextThread,
1431            IBinder token, Activity target, Intent[] intents, Bundle options) {
1432        IApplicationThread whoThread = (IApplicationThread) contextThread;
1433        if (mActivityMonitors != null) {
1434          ····
1447        }
1448        try {
1449           ·····
1454            int result = ActivityManagerNative.getDefault()
1455                .startActivities(whoThread, intents, resolvedTypes, token, options);
1456            checkStartActivityResult(result, intents[0]);
1457        } catch (RemoteException e) {
1458        }
1459    }


IApplicationThreadオブジェクト  がこのメソッドに渡されます。IApplicationThreadクラスはActivityThreadの内部クラスです。これはBinderのサブクラスであるため、このクラスの主な仕事はプロセス間で通信することです。メソッド内にはそのようなActivityManagerNative.getDefault()コードがあり、実際にはActivityManagerServiceのインスタンスを返しますActivityManagerServiceはstartActivityメソッドを呼び出します。ActivityManagerServiceはアクティビティ情報を記録した、Activityオブジェクト作成するコマンドIApplicationThreadに送信します。IApplicationThreadは、ActivityThreadが他のユーザーと通信するためのインターフェイスです

  IApplicationThreadは、ActivityManagerServiceからアクティビティ作成コマンドを受信すると、ハンドラーを介して作成メッセージActivityThreadに中継します。情報を受信したActivityThreadは独自のhandleLaunchActivity()メソッドを呼び出します。

  このメソッドの主な機能は、ActivityオブジェクトとApplicationオブジェクトを作成し、Activityのattachメソッドを実行し、ActivityライフサイクルでonCreateメソッドを呼び出すことです。handleLaunchActivityメソッド本体の主な内容は次のとおりです。 

 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2233        Activity a = performLaunchActivity(r, customIntent);此方法内部调用了Activity的attach方法
2235        if (a != null) {
2236            r.createdConfig = new Configuration(mConfiguration);
2237            Bundle oldState = r.state;
2238            handleResumeActivity(r.token, false, r.isForward,
2239                    !r.activity.mFinished && !r.startsNotResumed);  
2293    }


  Activityのattachメソッドの主な作業は、Windowを作成してWindowMangerインスタンスをバインドすることです。Window.setCallback()もあります。このメソッドは、主にActivityがユーザータッチイベントなどを受信できるようにするためのものです。

               mWindow = PolicyManager.makeNewWindow(this);
5191        mWindow.setCallback(this);
5192        mWindow.getLayoutInflater().setPrivateFactory(this);
5214        mWindow.setWindowManager(
5215                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
5216                mToken, mComponent.flattenToString(),
5217                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
5218        if (mParent != null) {
5219            mWindow.setContainer(mParent.getWindow());
5220        }
5221        mWindowManager = mWindow.getWindowManager();

   WindowMangerは、アクティビティがonCreateメソッドを実行する前に作成されており、setContentViewメソッドは通常oncreateで呼び出され、ビューの追加が完了します。

1948    public void setContentView(View view) {
1949        getWindow().setContentView(view);
1950        initActionBar();
1951    }

 
 

  アクティビティの作成が実行された後、 handleResumeActivityメソッドが実行されます。このメソッドは、主にアクティビティのDectorViewをWindowMnager追加するためのものです。このプロセスは、setContentViewのビューを画面に表示する操作です。
 final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
2798            boolean reallyResume) {
2803        ActivityClientRecord r = performResumeActivity(token, clearHide);
2804
2805        if (r != null) {
2806          ···········
2827            if (r.window == null && !a.mFinished && willBeVisible) {
2828                r.window = r.activity.getWindow();
2829                View decor = r.window.getDecorView();
2830                decor.setVisibility(View.INVISIBLE);
2831                ViewManager wm = a.getWindowManager();
2832                WindowManager.LayoutParams l = r.window.getAttributes();
2833                a.mDecor = decor;
2834                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
2835                l.softInputMode |= forwardBit;
2836                if (a.mVisibleFromClient) {
2837                    a.mWindowAdded = true;
2838                    wm.addView(decor, l);
2839                }
2895            // Tell the activity manager we have resumed.
2896            if (reallyResume) {
2897                try {
2898                    ActivityManagerNative.getDefault().activityResumed(token);
2899                } catch (RemoteException ex) {
2900                }
2901           
2904           ·····
2912    }
  
   
   

おすすめ

転載: blog.csdn.net/jiabailong/article/details/50972742