【Android話題-3.4アプリケーションプロセス】Contextへの理解について
25220 ワード
考察内容: Contextの役割を理解する Contextの初期化プロセス に詳しい異なるアプリケーションコンポーネント間のContextの違いを深く理解する いくつかの質問に答えます.アプリケーションにはContextがいくつありますか?Contextの違いは何ですか? ActivityのthisとgetBaseContextの違いは何ですか? getApplicationとgetApplicationContextの違いは何ですか? アプリケーションコンポーネントの構造、onCreate、attachBaseContext呼び出し順序?
Contextは抽象クラスです
その実装はすべてContextImplにある
Contextというアプリケーションコンポーネントがあるからこそ意味があり、システムサービスにアクセスしたり、システムリソースにアクセスしたりすることができます.ContextがなければActivityは普通のjavaオブジェクトにすぎません.
Contextはどこで作成されましたか?
どのコンポーネントに独自のContextがありますか? Application Activity Service(Broadcast、ContentProviderは独自のContextを持たない) Application Context
【Application Contextの初期化】:Application ContextはApplicationとともに初期化され、Applicationはアプリケーションプロセスの起動とともに初期化されます.アプリケーションプロセスの起動はどのようなものですか?まずzygoteがアプリケーションプロセスを作成し、アプリケーションプロセスが起動するとjavaクラスのエントリ関数、すなわちActivity Threadのmain関数が実行されます.この関数はAMSに報告されます:私はすでに起動しました.AMSが受信すると次のコマンド:Applicationを作成します.AMSはアプリケーションにApplicationを作成させ、アプリケーション側の処理関数は以下の通りである.
【アプリケーションの継承関係】:
Application自体がContextなのに、どうしてContextが入っているのでしょうか.これはなぜですか.Contextに関するすべての呼び出しが実際には中のmBaseオブジェクトに手を回していることがわかります.これは典型的な静的エージェントモードです.もし私たちが反射で中のmBaseオブジェクトを交換したらどうなりますか?たとえばgetSystemService関数を呼び出すと、別のContextのインプリメンテーションにジャンプする可能性があり、戻ってきたSystemService管理オブジェクトに手を加えることができます.このメカニズムは一般的にプラグインで使われます.
【Applicationの結論】:継承関係:Application
呼び出し順序:->attachBaseContext->onCreate ContextWraperにはContextが含まれており、呼び出しは に委任されています.
Activity Context
【Activity Contextの初期化】:ActivityのContextはActivityの起動に伴って一緒に初期化されます.
【Activityのクラス継承関係】:
【Activityの結論】: Activity
呼び出し順序->attachBaseContext->onCreate Service Context
【Service Contextの初期化】:
【サービスの継承関係】:
BroadcastReceiver
【ブロードキャスト結論】:ブロードキャストはContext抽象クラスを継承していない抽象クラスであり、Contextに関するグローバル変数もなく、onReceive抽象関数が1つしかなく、この関数にはパラメータ:Contextが付いている.動的に登録されたブロードキャストであれば、このContextはcontextを使用する.registeReceiver登録ブロードキャスト時に使用するcontext;静的に登録されたブロードキャストであれば、Activity Contextではなく、ApplicationをmBaseとするContextWrapperです.
ContentProvider
ContentProviderはブロードキャストと同じようにContextWrapperも継承されていませんが、その中にmContextメンバー変数があります.ContextProviderが初期化されたときに外から伝わり、Application Contextが伝わります.ちなみにContentProviderの初期化はApplicationのコンストラクション関数およびattachBaseContextの後ですが、アプリケーションです.onCreate()の前に呼び出されました.つまりContentProviderのonCreateはアプリケーションよりもonCreateは早いです.
いくつかの質問に答えます.アプリケーションにはContextがいくつありますか?Contextの違いは何ですか?a)Activityの数+Serviceの数+Applicationの数.アプリケーションはマルチプロセスである可能性があるため、アプリケーションは複数ある可能性があります.違い:ActivityはUIを表示するためContextThemeWrapperを継承し、ServiceやApplicationのような非UIコンポーネントはContextWrapperを直接継承します. ActivityのthisとgetBaseContextの違いは何ですか?A:ActivityはContextを継承しているので、これはActivityオブジェクト自身に戻ります.getBaseContextはContextWrapperの中のmBaseを返します. getApplicationとgetApplicationContextの違いは何ですか?答:getApplicationContext()はcontextの抽象関数であり、getApplication()はActivityとServiceに特有のものである.例えば、ブロードキャストのonReciever(context)のcontextはgetApplication()を調整できず、getApplicationContext()を調整するしかない. アプリケーションコンポーネントの構造、onCreate、attachBaseContext呼び出し順序?A:コンポーネント構築関数->attachBaseContext->onCreate あなたのContextに対する理解を話します Contextの役割a)Contextはアプリケーションのコンテキストであり、Contextアプリケーションコンポーネントがあればシステムリソースにアクセスしやすく、システムサービス を呼び出すことができる.はアプリケーションの中にいくつかのContextがあることを言い出して、それぞれ関係 を継承します Contextの初期化プロセス について説明する
Contextは抽象クラスです
public abstract calss Context{
public abstract Resources getResources();
public abstract Object getSystemService(String name);
public abstract void startActivty(Intent intent);
public abstract void sendBroadcast(Intent intent);
......
}
その実装はすべてContextImplにある
class ContextImpl extends Context{
final ActivityThread mMainThread; //
final LoadedApk mPackageInfo; //
private final ResourcesManager mResourcesManager; //
private final Resources mResources;
private Resoures.Theme mThreme = null; //
private PackageManager mPackageManager; //
//
final Object] mServiceCache = SystemServiceRegistry.createServiceCache();
}
Contextというアプリケーションコンポーネントがあるからこそ意味があり、システムサービスにアクセスしたり、システムリソースにアクセスしたりすることができます.ContextがなければActivityは普通のjavaオブジェクトにすぎません.
Contextはどこで作成されましたか?
どのコンポーネントに独自のContextがありますか?
【Application Contextの初期化】:Application ContextはApplicationとともに初期化され、Applicationはアプリケーションプロセスの起動とともに初期化されます.アプリケーションプロセスの起動はどのようなものですか?まずzygoteがアプリケーションプロセスを作成し、アプリケーションプロセスが起動するとjavaクラスのエントリ関数、すなわちActivity Threadのmain関数が実行されます.この関数はAMSに報告されます:私はすでに起動しました.AMSが受信すると次のコマンド:Applicationを作成します.AMSはアプリケーションにApplicationを作成させ、アプリケーション側の処理関数は以下の通りである.
private void handleBindApplication(AppBindData data){
// Application
Application app = data.info.makeApplication(...);
// onCreate
app.onCreate();
}
public Application makeApplication(...){
// Context: newContextImpl(...)
ContextImpl appContext = ContextImpl.createAppContext(...);
Application app;
// Application , appContext
app = mActivityThread.mInstrumentation.newApplication(appContext);
return app;
}
// Application :
application newApplication(ClassLoader cl, String className, Context context){
// classLoader Application
return newApplication(cl.loadClass(className), context);
}
Application newApplication(Class<?> clazz, Context context){
// newInstance
//newInstance , Application
Application app = (Application)clazz.newInstance();
// app context
app.attach(context); // attachBaseContext(context);
return app;
}
【アプリケーションの継承関係】:
public class Application extends ContextWrapper{
......
}
public class ContextWrapper extends Context{
Context mBase;
protected void attachBaseContext(Context base){
mBase = base;
}
public Context getBaseContext(){
return mBase;
}
@Overrid
public Resources getResources() {
return mBase.getResources();
}
@Override
public Object getSystemService(String name) {
return mBase.getSystemService(name);
}
@Override
public void startActivity(Intent intent) {
mBase.startActivity(intent);
}
}
Application自体がContextなのに、どうしてContextが入っているのでしょうか.これはなぜですか.Contextに関するすべての呼び出しが実際には中のmBaseオブジェクトに手を回していることがわかります.これは典型的な静的エージェントモードです.もし私たちが反射で中のmBaseオブジェクトを交換したらどうなりますか?たとえばgetSystemService関数を呼び出すと、別のContextのインプリメンテーションにジャンプする可能性があり、戻ってきたSystemService管理オブジェクトに手を加えることができます.このメカニズムは一般的にプラグインで使われます.
【Applicationの結論】:
Activity Context
【Activity Contextの初期化】:ActivityのContextはActivityの起動に伴って一緒に初期化されます.
private Activity performLaunchActivity(){
Activity activity = null;
// Actvity
activity mInstrumentation.newActivity();
// application
Application app = r.packageInfo.makeApplication();
// Activity Context: new ContextImpl()
Context appContext = createBaseContextForActivity(r, activity);
// appContext application activity
activity.attach(appContext, app, ...); // attachBaseContext(context);
// Activity
activity.onCreate();
return activity;
}
public Activity newActivity(ClassLoader cl, String className){
// ClassLoader Activity , newInstance Acivity , Activity
return (Activity)cl.loadClass(className).newInstance();
}
【Activityのクラス継承関係】:
public class Activity extends ContextThemeWrapper{
...
}
public class ContextThemeWrapper extends ContextWrapper{
private int mThemeResource;
private Resources.Theme mTheme;
private LayoutInflater mInflater;
private Configuration mOverrideConfiguration;
private Resources mResources;
}
public class ContextWrapper extends Context{
Context mBase;
......
}
【Activityの結論】:
【Service Contextの初期化】:
private void handleCreateService(CreateServiceData data) {
Servie service = null;
// classLoader Service , newInstance
//newInstance Service Service
servie = (Service)cl.loadClass(data.info.name).newInstance();
// Context: new ContextImpl(...)
ContextImpl context = ContextImpl.createAppContext(this, packageInfo)
context.setOuterContext(service);
// application
Application app = packageInfo.makeApplication();
// context application service
service.attach(context, app); // attachBaseContext(context);
// Service
servcie.onCreate();
}
【サービスの継承関係】:
public abstract class Service extends ContextWrapper{
......
}
BroadcastReceiver
public abstract class BroadcastReceiver {
public abstract void onReceive(Context context, Intent intent);
......
}
【ブロードキャスト結論】:ブロードキャストはContext抽象クラスを継承していない抽象クラスであり、Contextに関するグローバル変数もなく、onReceive抽象関数が1つしかなく、この関数にはパラメータ:Contextが付いている.動的に登録されたブロードキャストであれば、このContextはcontextを使用する.registeReceiver登録ブロードキャスト時に使用するcontext;静的に登録されたブロードキャストであれば、Activity Contextではなく、ApplicationをmBaseとするContextWrapperです.
ContentProvider
public abstract class ContentProvider {
private Context mContext = null;
......
}
ContentProviderはブロードキャストと同じようにContextWrapperも継承されていませんが、その中にmContextメンバー変数があります.ContextProviderが初期化されたときに外から伝わり、Application Contextが伝わります.ちなみにContentProviderの初期化はApplicationのコンストラクション関数およびattachBaseContextの後ですが、アプリケーションです.onCreate()の前に呼び出されました.つまりContentProviderのonCreateはアプリケーションよりもonCreateは早いです.
いくつかの質問に答えます.