Android framework:contextの理解
9701 ワード
慕課網frameworkノート
3-4 contextに対する理解について述べる
考察:
contextの役割を理解する
context初期化プロセスに詳しい
異なるアプリケーションコンポーネント間のcontextの違いを深く理解する
質問に答える:
1,アプリケーションの中で何個のcontextを使って、異なったcontextの間は上から区別します
2,ActivityのthisとgeteBaseContextの違い
3,getApplicationとgetApplicationContextの違い
4,アプリケーションコンポーネントの構築,onCreate,attachBaseContext呼び出し順序
1,contextの役割
contextクラスの定義を見てみましょう.抽象クラスで、インタフェースではありません.これは注意してください.
注釈を見て、このクラスを理解するのに役立ちます.
contextがあるからこそ、これらのアプリケーションコンポーネントは意味があり、システムサービス、システムリソースにアクセスすることができます.
contextがなければActivityは普通のjavaオブジェクトにすぎず、
皇帝のように、様々な機構がなければ、このような大きな江山を管理することはできません.もし権利がなければ、皇帝は普通の人です.
Activityが皇帝であればcontextは権力であり,権力があれば各リソースを呼び出すことができる.
2,contextはどこで作成しますか?」?
まず、どのcontextがあるか、つまりどのコンポーネントが独自のcontextを持っているかを理解します.
Applicatoin,Activity,Service,
放送とcontent providerには自分のcontext'がありません
まずApplication contextを見て
Application contextはApplicationとともに初期化され、ApplicationはAPプロセスの起動とともにinitされます.
APプロセス起動プロセス:
zygote fork->AP、AP起動後javaクラスのエントリ関数(Activity Threadのmain)を起動します.この関数はAMSに起動が報告されます.
AMSが受信すると、APにApplicationを作成させるコマンドが発行されます.
AP処理の関数:
反射でmBaseオブジェクトを交換すると、
getSystemServiceを呼び出すと、別のcontextインプリメンテーションにジャンプし、返されるSystem Service管理オブジェクトに手を加えることができます.
このメカニズムは一般的にプラグインで使用されます.
Applicationの結論:
継承関係:アプリケーション
呼び出し順序:(Applicationのコンストラクション関数)=>attachBaseContext(contextの設定)="onCreate
ContextWrapperにはContextが含まれています.呼び出しはすべて依頼されます.mBaseでしょう.
2,ActivityのContextはどのように初期化しますか?
Activityが起動したときに一緒にinitしたものです
Activityの起動を確認します.
アプリケーションと同様のプロセスが表示されます.
コンポーネントオブジェクトを作成し、コンポーネントにcontextを作成し、contextを割り当て、コンポーネントのonCreateライフサイクルを呼び出します.
3,initプロセスを終了し,Activityのクラス継承関係を見る.
ActivityとApplicationは少し異なり、ContextThemeWrapperから継承されています.
Activityの結論:
クラス継承関係:Activity
ApplicationはContextWrapperを直接継承していますが、Activityはインタフェースの展示も担当しているので、ContextThemeWrapperという層が1つ増えています.
呼び出し順序:(Activityのコンストラクション関数、contextの作成)->attachBaseContext(contextをActivityに割り当てる)->onCreate
4、サービスを見て
サービスはアプリケーションと同様にContextWrapperから継承されており、インタフェースを表示する必要はありません.
public abstract class Service extend ContextWrapper{...}
サービスの初期化:
5、ラジオを見て
抽象クラスであり、ContextWrapperもContextのメンバー変数も継承されていません.
パラメータcontextはonReceve関数が1つしかありません
public bastract class BoradcastReceiver{ public adstract void onReceive(Context context, Intent intent); .... }
ブロードキャストが動的に登録する場合、contextはブロードキャストを登録する際に用いるcontext:contextである.registerReceiver
静的登録であれば、これもApplicationのcontextではありません.ApplicatoinをmBaseとするContextWrapperで、後で話したいです.ここで結論を記す.
6 contentProviderを見て
ContextWrapperも継承されていませんが、contextメンバー変数があります.
これはCOntextProvider初期化時に渡された、渡されたApplicatoinのcontextで、
ContextProviderの初期化はApplicationのコンストラクション関数とAttachBaseContextの後ですが、
しかし、アプリケーションのonCreateの前に呼び出されました.
だから、ContextProviderのonCreateはApplicationのonCreateより早いので、これは注意しましょう
public abstract class ContentProvider{ private Context mContext = null; .... }
質問に戻ります.
1,APには何個のcontextがありますか.異なるcontextにはどんな違いがありますか.
Apの中にはApplication,Activity,Serviceだけが自分のcontextを持っていて、
ブロードキャストとContextProviderはありませんが、
何個のcontextがあるか計算してみましょう
Activity個数+Service個数+Application個数、Applicationはプロセスに従っているので、contextが複数ある可能性があります.
違い:
ActivityはUIを表示するので、ContextThemeWraperを継承し、ApplicatoinとserviceはContextWrapperを継承しますが表示する必要はありません.
2,ActivvytのthisとgetBaseContextの違いは何ですか?
Activityはcontextを継承するので、これはActivity自身に戻ります.
getBaseContextはContextWrapperの中のmBaseを返します.
3,getApplicationとgetApplicationContextの違いは何ですか?
いずれもApplicatoinオブジェクトを返します.getApplicationContextはcontextの抽象関数です.
getApplicatoinはActivityやサービスに特有で、他の場所では使えませんが、
ブロードキャストの場合、onReceive()の最初のパラメータは、このcontextを取得するとgetApplicationを呼び出すことができないgetApplicationContextのみを呼び出すことができます.
4,アプリケーションコンポーネントの構築,onCreate,attachBaseContext呼び出し順序
コンポーネントのコンストラクション関数を呼び出し、次にattach context、最後にonCreate
まとめ:
1,Contextの役割をはっきり説明する:
アプリケーションコンポーネントのコンテキストであり、contextがあれば、アプリケーションコンポーネントはシステムリソースにアクセスしやすく、システムサービスを呼び出すことができます.
2,APにはいくつかのコンポーネントがあります.自分のcontextがあります.彼らはどんな違いがありますか.継承関係はどうですか.
3,contextの初期化プロセスについて
3-4 contextに対する理解について述べる
考察:
contextの役割を理解する
context初期化プロセスに詳しい
異なるアプリケーションコンポーネント間のcontextの違いを深く理解する
質問に答える:
1,アプリケーションの中で何個のcontextを使って、異なったcontextの間は上から区別します
2,ActivityのthisとgeteBaseContextの違い
3,getApplicationとgetApplicationContextの違い
4,アプリケーションコンポーネントの構築,onCreate,attachBaseContext呼び出し順序
1,contextの役割
contextクラスの定義を見てみましょう.抽象クラスで、インタフェースではありません.これは注意してください.
注釈を見て、このクラスを理解するのに役立ちます.
//interface to global information about an application environment.
//this is an abstract class whose implimentation is provided by the android system.
//it allows access to application-specific resources and classes,as well as up-calls for application-level operations
//such as launching activities, boradcasting and receiving intents,etc.
// ,
// , android ,
// , AP , AP activity, , intents
// context ,
public abstract class Context{
public abstract Resources getResources(); //
public abstract Object getSystemService(String name); //
public abstract void startActivity(Intent intent); // Acitivity
public abstract void sendBroadcast(Intent intent); //
......
}
// , ContextImpl
// , ,
class ContextImpl extends Context{
final ActivityThead mMainThread; //
final LoadedApk mPackageInfo; //
//
private final ResourcesManager mResourcesManager;
private final Resource mResources;
private Resources.Theme mTheme = null; //
private PackageManager mPackageManager; //
final Object[] mServiceCache =
SystemServiceRegistry.createServiceCache(); //
}
contextがあるからこそ、これらのアプリケーションコンポーネントは意味があり、システムサービス、システムリソースにアクセスすることができます.
contextがなければActivityは普通のjavaオブジェクトにすぎず、
皇帝のように、様々な機構がなければ、このような大きな江山を管理することはできません.もし権利がなければ、皇帝は普通の人です.
Activityが皇帝であればcontextは権力であり,権力があれば各リソースを呼び出すことができる.
2,contextはどこで作成しますか?」?
まず、どのcontextがあるか、つまりどのコンポーネントが独自のcontextを持っているかを理解します.
Applicatoin,Activity,Service,
放送とcontent providerには自分のcontext'がありません
まずApplication contextを見て
Application contextはApplicationとともに初期化され、ApplicationはAPプロセスの起動とともにinitされます.
APプロセス起動プロセス:
zygote fork->AP、AP起動後javaクラスのエントリ関数(Activity Threadのmain)を起動します.この関数はAMSに起動が報告されます.
AMSが受信すると、APにApplicationを作成させるコマンドが発行されます.
AP処理の関数:
private void handleBindApplication(AppBindData data){
// Application
Application app = data.info.makeApplication(...);
// onCreate
app.onCreate();
}
// Application
public Application makeApplication(...){
// context, new ContextImpl(...)
ContextImpl appContext = ContextImpl.createAppContext(...);
Application app;
// Application , context ,
app = mActivityThread.mInstrumentation.newApplication(appContext);
return app;
}
// Application
Application newApplication(ClassLoader cl, String className, Context context){
// classload Applicatoin
return newApplication(cl.loadClass(className), context);
}
Application newApplication(Class> clazz, Context context)
{
//newInstance , Application ,
Application app = (Application)clazz.newInstance();
// Application context
// attachBaseContext(),
app.attach(context);
return app;
}
// attachBaseContext, Application :
//application ContextWrapper
public class Application extends ContextWrapper{
...
}
//ContextWrapper context,
public class ContextWrapper extends Context{
Context mBase;
// ContextWrapper mBase ,mBase context,
//ContextWrapper Context, context?
protected void attachBaseContext(Context base){
mBase = base;
}
public Context getBaseContext(){
return mBase;
}
}
//ContextWrapper Context, context?
// ContextWrapper context mBase ,
//
public class ContextWrapper extends Context{
Context mBase;
@Override
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);
}
}
反射でmBaseオブジェクトを交換すると、
getSystemServiceを呼び出すと、別のcontextインプリメンテーションにジャンプし、返されるSystem Service管理オブジェクトに手を加えることができます.
このメカニズムは一般的にプラグインで使用されます.
Applicationの結論:
継承関係:アプリケーション
呼び出し順序:(Applicationのコンストラクション関数)=>attachBaseContext(contextの設定)="onCreate
ContextWrapperにはContextが含まれています.呼び出しはすべて依頼されます.mBaseでしょう.
2,ActivityのContextはどのように初期化しますか?
Activityが起動したときに一緒にinitしたものです
Activityの起動を確認します.
private Activity performLaunchActivity(){
Activity activity = null;
//
activity = mInstrumentation.newActivity();
//Application ,
Application app = r.packageInfo.makeApplication();
// Activity context:new ContextImpl(...)
Context appContext = createBaseContextForActivity(r, activity);
// context activity,
//attach attachbaseContext(context); context Activity mBase
//mBase ContextWrapper ,
activity.attach(appContext, app,...);
// onCreate 。
activity.onCreate();
return activity;
}
//newActivity newApplication ,loadClass , NewInstance
public Activity newActivity(ClassLoader cl, String className){
return (Activity)cl.loadClass(className).newInstance();
}
アプリケーションと同様のプロセスが表示されます.
コンポーネントオブジェクトを作成し、コンポーネントにcontextを作成し、contextを割り当て、コンポーネントのonCreateライフサイクルを呼び出します.
3,initプロセスを終了し,Activityのクラス継承関係を見る.
ActivityとApplicationは少し異なり、ContextThemeWrapperから継承されています.
public class Activity extends ContextThemeWrapper{...}
// ContextWrapper Theme,
public class ContextThemeWrapper extends ContextWrapper{
// , , , Activity
// , Context , ContextWrapper mBase
private int mThemeResource;
private Resources.Theme mTheme;
private LayhoutInflater mInflater;
private Configuration mOverrideConfiguiration;
private Resources mResources;
}
Activityの結論:
クラス継承関係:Activity
ApplicationはContextWrapperを直接継承していますが、Activityはインタフェースの展示も担当しているので、ContextThemeWrapperという層が1つ増えています.
呼び出し順序:(Activityのコンストラクション関数、contextの作成)->attachBaseContext(contextをActivityに割り当てる)->onCreate
4、サービスを見て
サービスはアプリケーションと同様にContextWrapperから継承されており、インタフェースを表示する必要はありません.
public abstract class Service extend ContextWrapper{...}
サービスの初期化:
private void handleCreateService(CreateServiceData data){
Service service = null;
// ClassLoader service , newInstance , service
service = (Service) cl.loadClass(data.info.name).newInstance();
// context, new ContextImpl(...)
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
// service Applicatoin, makeApplication, Application 。
Application app = packageInfo.makeApplication();
// Context Application Service
// attachBaseContext(context), Application , Context ContextWrapper mBase
service.attach(context, app);
// service onCreate
service.onCreate();
}
5、ラジオを見て
抽象クラスであり、ContextWrapperもContextのメンバー変数も継承されていません.
パラメータcontextはonReceve関数が1つしかありません
public bastract class BoradcastReceiver{ public adstract void onReceive(Context context, Intent intent); .... }
ブロードキャストが動的に登録する場合、contextはブロードキャストを登録する際に用いるcontext:contextである.registerReceiver
静的登録であれば、これもApplicationのcontextではありません.ApplicatoinをmBaseとするContextWrapperで、後で話したいです.ここで結論を記す.
6 contentProviderを見て
ContextWrapperも継承されていませんが、contextメンバー変数があります.
これはCOntextProvider初期化時に渡された、渡されたApplicatoinのcontextで、
ContextProviderの初期化はApplicationのコンストラクション関数とAttachBaseContextの後ですが、
しかし、アプリケーションのonCreateの前に呼び出されました.
だから、ContextProviderのonCreateはApplicationのonCreateより早いので、これは注意しましょう
public abstract class ContentProvider{ private Context mContext = null; .... }
質問に戻ります.
1,APには何個のcontextがありますか.異なるcontextにはどんな違いがありますか.
Apの中にはApplication,Activity,Serviceだけが自分のcontextを持っていて、
ブロードキャストとContextProviderはありませんが、
何個のcontextがあるか計算してみましょう
Activity個数+Service個数+Application個数、Applicationはプロセスに従っているので、contextが複数ある可能性があります.
違い:
ActivityはUIを表示するので、ContextThemeWraperを継承し、ApplicatoinとserviceはContextWrapperを継承しますが表示する必要はありません.
2,ActivvytのthisとgetBaseContextの違いは何ですか?
Activityはcontextを継承するので、これはActivity自身に戻ります.
getBaseContextはContextWrapperの中のmBaseを返します.
3,getApplicationとgetApplicationContextの違いは何ですか?
いずれもApplicatoinオブジェクトを返します.getApplicationContextはcontextの抽象関数です.
getApplicatoinはActivityやサービスに特有で、他の場所では使えませんが、
ブロードキャストの場合、onReceive()の最初のパラメータは、このcontextを取得するとgetApplicationを呼び出すことができないgetApplicationContextのみを呼び出すことができます.
4,アプリケーションコンポーネントの構築,onCreate,attachBaseContext呼び出し順序
コンポーネントのコンストラクション関数を呼び出し、次にattach context、最後にonCreate
まとめ:
1,Contextの役割をはっきり説明する:
アプリケーションコンポーネントのコンテキストであり、contextがあれば、アプリケーションコンポーネントはシステムリソースにアクセスしやすく、システムサービスを呼び出すことができます.
2,APにはいくつかのコンポーネントがあります.自分のcontextがあります.彼らはどんな違いがありますか.継承関係はどうですか.
3,contextの初期化プロセスについて