ActivityManagerService(一)
19037 ワード
文章の出所:http://blog.csdn.net/shift_wwwx
前書き:前のAndroid SystemServerを詳しく分析してみました.systeemServerの起動過程は複雑な分析が多いですが、systemserverはandroid起動の第一歩です.多くのserviceはこのプロセスで起動しています.これらこそがandroidを構成する鍵です.AMSはandroidアプリケーションの一番重要なserviceと言えます.伝説のアンディの4つのコンポーネントはそれで制御します.ソースコードによって分析しますが、足りないところが多いと思います.
AMSが最初に関与したのは、systemserverである:
1)AThread
いくつかの変数の注意が必要です.mBroadcastQues、mbgBroadcastQue、mBgBroadcastQue、mServices、mProvider Mapの4つのコンポーネントがここに現れました.もう一つの後期に紹介します.他の変数もあります.mBatteryStats Service、mProcess Stats、mUsageStats Service、mApp OpsService、mGrantFile、mStartdeUsers、mComppartModePackage、mProcess CputThreadなど.
コードから見れば、/data/system/の下で、いくつかのファイルを作成してandroidシステムの状態を管理しています.例えば、batterystats.binは電池状態です.そして、procstats管理プロセスのapps.xmlはapp権限に関するものです.
2)上記でAThread後mSelf=mを分析します.
mSelfはstaticタイプで、以下に述べるmSystemThreadもstaticです.
3)ActivityThread.systemmain()
ddmはDalvik Debug Monitorの略語で、
具体的に何がよく分かりませんか?誰が教えてくれますか?
(2)Instruumentation類
(3)context
contextが初めて本当に現れたのはここです.
まずget System Contect():
引き続き見て、contextはContectImpl.creat SystemConteextを通じて(this)です.を選択して作成しました
android zygoteの起動過程分析で言及したzygoteInit.main?その中にpreloadがあります.そしてその後
Androidシステムのリソースのロードと取得は、解析プロセスの中で最も重要なものです.
Resources.get Systemを説明しました.context.init関数を見てみます.
LoadedAnkはゲームを作成した後、もう一回context.initを呼び出します.
ここまでのActivityThreadのこのstatic mSystemContextは完全に作成okです.
最初に戻って、ここでcontextは本当に初めてです.ここでcontext.initとgets SystemConteextの中のcontext.initが重複しています.googleは当初どう思っていましたか?
(4)アプリオブジェクトの作成
最初はよく分かりませんでしたが、全体の過程はいったい何をしていますか?全体的なものではなく、一部のcontext変数を表示します.このcontextを利用してinitを作って、initの時にLoadedAkに入ってきます.これはappkのすべての関連情報の集合です.なぜここに現れますか?このActivityThreadにおけるatch関数の本当の目的が完全に分かりました.
LoadedAnkの構造関数を振り返ってみます.
このandroidアプリも彼のAndroid Manifest.xmlを提出しました.このAndroidアプリは一体何ですか?bingoとは、frame ework.ress.appkのことです.
(5)DropBox.set Report(new Drop BoxReport();
(6)View RootImpl.addConfigCallback(new ComponentCallbacks 2(){}
View RootImplにConfigrationChangedイベントを受信するために登録します.Windows Managerを紹介する時に、dispatchのような事件が具体的なactivityの中にあれば分析します.
4)ActivityThreadで分析した後、mSystemThread=at;ここのmSystemThreadとmSelfは全部staticです.
5)AMSを初期化するmContect、mFactoryTest、mIntent Firewall、mStock Supervisor
6)m.startRunning(null、null、null、null);
ここまでActivityManager Service.mainは全部解析しました.
まとめてみます
mainのAThreadでlooperを作成し、AMS、つまりmSelfを実例化しました.次に、ActivityThreadというstaticのActivityThreadを実例化しました.つまり、mSystemThreadは、ActivityThreadの中でAppplicationを実行しました.frame ew-rek.appkです.続いていくつかの設定があります.mConteext、mFactoryTest、mIntent Firewall、mStockSupervisor、mBatteryStats Service、mUsageStats Service、mAppOppServiceなどです.スターリング.
前書き:前のAndroid SystemServerを詳しく分析してみました.systeemServerの起動過程は複雑な分析が多いですが、systemserverはandroid起動の第一歩です.多くのserviceはこのプロセスで起動しています.これらこそがandroidを構成する鍵です.AMSはandroidアプリケーションの一番重要なserviceと言えます.伝説のアンディの4つのコンポーネントはそれで制御します.ソースコードによって分析しますが、足りないところが多いと思います.
AMSが最初に関与したのは、systemserverである:
context = ActivityManagerService.main(factoryTest);
public static final Context main(int factoryTest) {
AThread thr = new AThread();// Looper, AMS
thr.start();
synchronized (thr) {
while (thr.mService == null) {// AMS
try {
thr.wait();
} catch (InterruptedException e) {
}
}
}
ActivityManagerService m = thr.mService;//mSelf AMS
mSelf = m;
ActivityThread at = ActivityThread.systemMain();// ActivityThread
mSystemThread = at;
Context context = at.getSystemContext();
context.setTheme(android.R.style.Theme_Holo);
m.mContext = context;
m.mFactoryTest = factoryTest;
m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface());
m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper);//activity
m.mBatteryStatsService.publish(context);
m.mUsageStatsService.publish(context);
m.mAppOpsService.publish(context);
synchronized (thr) {//mSelf , AThread Looper loop
thr.mReady = true;
thr.notifyAll();
}
m.startRunning(null, null, null, null);// startRuuning
return context;
}
は、コード内のコメントに注意する.1)AThread
static class AThread extends Thread {
ActivityManagerService mService;
Looper mLooper;
boolean mReady = false;
public AThread() {
super("ActivityManager");
}
@Override
public void run() {
Looper.prepare();
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
ActivityManagerService m = new ActivityManagerService();
synchronized (this) {
mService = m;
mLooper = Looper.myLooper();
Watchdog.getInstance().addThread(new Handler(mLooper), getName());
notifyAll();
}
synchronized (this) {
while (!mReady) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
// For debug builds, log event loop stalls to dropbox for analysis.
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
}
Looper.loop();
}
}
これはAMSの中のstatic classです.AMSのためにthreadを作成しました.serverプロセスのmain threadは、AMSのためにLooperを作成し、次にLooper.loop()を呼び出します.もう一つの目的はAMSの実装です.private ActivityManagerService() {
Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT, false);
mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT, true);
mBroadcastQueues[0] = mFgBroadcastQueue;
mBroadcastQueues[1] = mBgBroadcastQueue;
mServices = new ActiveServices(this);
mProviderMap = new ProviderMap(this);
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
systemDir.mkdirs();
......
}
コンストラクションは詳しくないです.AMS.javaのsource codeを見てください.いくつかの変数の注意が必要です.mBroadcastQues、mbgBroadcastQue、mBgBroadcastQue、mServices、mProvider Mapの4つのコンポーネントがここに現れました.もう一つの後期に紹介します.他の変数もあります.mBatteryStats Service、mProcess Stats、mUsageStats Service、mApp OpsService、mGrantFile、mStartdeUsers、mComppartModePackage、mProcess CputThreadなど.
コードから見れば、/data/system/の下で、いくつかのファイルを作成してandroidシステムの状態を管理しています.例えば、batterystats.binは電池状態です.そして、procstats管理プロセスのapps.xmlはapp権限に関するものです.
2)上記でAThread後mSelf=mを分析します.
mSelfはstaticタイプで、以下に述べるmSystemThreadもstaticです.
3)ActivityThread.systemmain()
public static ActivityThread systemMain() {
HardwareRenderer.disable(true);// hardwareRenderer
ActivityThread thread = new ActivityThread();// ResourceManager
thread.attach(true);
return thread;
}
主にActivityThread.atch()です. private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
} else {
// Don't set application object here -- if the system crashes,
// we can't display an alert, we just want to die die die.
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try {
mInstrumentation = new Instrumentation();
ContextImpl context = new ContextImpl();
context.init(getSystemContext().mPackageInfo, null, this);
Application app = Instrumentation.newApplication(Application.class, context);
mAllApplications.add(app);
mInitialApplication = app;
app.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
// add dropbox logging to libcore
DropBox.setReporter(new DropBoxReporter());
ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
synchronized (mResourcesManager) {
// We need to apply this change to the resources
// immediately, because upon returning the view
// hierarchy will be informed about it.
if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
// This actually changed the resources! Tell
// everyone about it.
if (mPendingConfiguration == null ||
mPendingConfiguration.isOtherSeqNewer(newConfig)) {
mPendingConfiguration = newConfig;
sendMessage(H.CONFIGURATION_CHANGED, newConfig);
}
}
}
}
@Override
public void onLowMemory() {
}
@Override
public void onTrimMemory(int level) {
}
});
}
(1)android.ddm.DdmHandleApple.setApName(「system upcess」、UserHandle.mUserId();ddmはDalvik Debug Monitorの略語で、
具体的に何がよく分かりませんか?誰が教えてくれますか?
(2)Instruumentation類
(3)context
contextが初めて本当に現れたのはここです.
ContextImpl context = new ContextImpl();
context.init(getSystemContext().mPackageInfo, null, this);
ここのcontextは関数内の局部変数ですが、本当にやることが多いです.まずget System Contect():
public ContextImpl getSystemContext() {
synchronized (this) {
if (mSystemContext == null) {
ContextImpl context =
ContextImpl.createSystemContext(this);
LoadedApk info = new LoadedApk(this, "android", context, null,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);
context.init(info, null, this);
context.getResources().updateConfiguration(mResourcesManager.getConfiguration(),
mResourcesManager.getDisplayMetricsLocked(Display.DEFAULT_DISPLAY));
mSystemContext = context;
//Slog.i(TAG, "Created system resources " + context.getResources()
// + ": " + context.getResources().getConfiguration());
}
}
return mSystemContext;
}
ここの主な目的はmSystemContectを作成することです.static ContextImpl mSystemContext = null;
これはシステムがずっと使っていますので、上記のcontextは臨時ですが、目的は肝心です.引き続き見て、contextはContectImpl.creat SystemConteextを通じて(this)です.を選択して作成しました
static ContextImpl createSystemContext(ActivityThread mainThread) {
final ContextImpl context = new ContextImpl();
context.init(Resources.getSystem(), mainThread, Process.myUserHandle());
return context;
}
は、Resources.get Sytem(): public static Resources getSystem() {
synchronized (sSync) {
Resources ret = mSystem;
if (ret == null) {
ret = new Resources();
mSystem = ret;
}
return ret;
}
}
覚えていますandroid zygoteの起動過程分析で言及したzygoteInit.main?その中にpreloadがあります.そしてその後
Androidシステムのリソースのロードと取得は、解析プロセスの中で最も重要なものです.
mResources = Resources.getSystem();
です.このmSystemはstaticです.だからここでretはzygoteの時に決められました.これからはnullになりません.Resourceを含むコンストラクションの中のmAsssetsもstaticタイプです.これもzygoteの時に定義されました.Resources.get Systemを説明しました.context.init関数を見てみます.
final void init(Resources resources, ActivityThread mainThread, UserHandle user) {
mPackageInfo = null;
mBasePackageName = null;
mOpPackageName = null;
mResources = resources;
mMainThread = mainThread;
mContentResolver = new ApplicationContentResolver(this, mainThread, user);
mUser = user;
}
はsystem contextとして、この時mPackage Infoなどはnullです.ActivityThreadに戻って、gets SystemCotextを見続けて、createSystem Contextを説明しました.ずっと見ているpackage Infoを見てください.この対象のタイプはLoadedAkです.LoadedApk info = new LoadedApk(this, "android", context, null,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);
LoadedAkはappkをロードする関連カテゴリで、詳細なcodeは貼っていません.Loadedアプリには2つの構成関数があり、一つは普通のappkに対して、もう一つはsystemboxtに対するものです.ここのコンストラクタはApplication Infoを作成することを目的としています.またmClass Loader、mResourceなどですが、mApplication Info.package Name、mPackage Nameはすべて「android」に等しいです.このLoadedAnk構造関数に注意してください.この「android」などが紹介されます.LoadedAnkはゲームを作成した後、もう一回context.initを呼び出します.
final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread) {
init(packageInfo, activityToken, mainThread, null, null, Process.myUserHandle());
}
final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread,
Resources container, String basePackageName, UserHandle user) {
mPackageInfo = packageInfo;
if (basePackageName != null) {
mBasePackageName = mOpPackageName = basePackageName;
} else {
mBasePackageName = packageInfo.mPackageName;
ApplicationInfo ainfo = packageInfo.getApplicationInfo();
if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) {
// Special case: system components allow themselves to be loaded in to other
// processes. For purposes of app ops, we must then consider the context as
// belonging to the package of this process, not the system itself, otherwise
// the package+uid verifications in app ops will fail.
mOpPackageName = ActivityThread.currentPackageName();
} else {
mOpPackageName = mBasePackageName;
}
}
mResources = mPackageInfo.getResources(mainThread);
mResourcesManager = ResourcesManager.getInstance();
CompatibilityInfo compatInfo =
container == null ? null : container.getCompatibilityInfo();
if (mResources != null &&
((compatInfo != null && compatInfo.applicationScale !=
mResources.getCompatibilityInfo().applicationScale)
|| activityToken != null)) {
if (DEBUG) {
Log.d(TAG, "loaded context has different scaling. Using container's" +
" compatiblity info:" + container.getDisplayMetrics());
}
if (compatInfo == null) {
compatInfo = packageInfo.getCompatibilityInfo();
}
mDisplayAdjustments.setCompatibilityInfo(compatInfo);
mDisplayAdjustments.setActivityToken(activityToken);
mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
Display.DEFAULT_DISPLAY, null, compatInfo, activityToken);
} else {
mDisplayAdjustments.setCompatibilityInfo(packageInfo.getCompatibilityInfo());
mDisplayAdjustments.setActivityToken(activityToken);
}
mMainThread = mainThread;
mActivityToken = activityToken;
mContentResolver = new ApplicationContentResolver(this, mainThread, user);
mUser = user;
}
ここではさらなる初期化mSystemContectであるべきです.以前のinitによると、mPackage Infoなどは全部nullです.ここで詳細な割り当てを行います.mPackage Infoは前に作成したLoadedArkです.mBasePackage Name、mOpPackage Nameは全部前にLoadedAkを作成して伝えられた「android」です.mResource、mResource Managerはもちろん、以前に紹介しました.ここまでのActivityThreadのこのstatic mSystemContextは完全に作成okです.
最初に戻って、ここでcontextは本当に初めてです.ここでcontext.initとgets SystemConteextの中のcontext.initが重複しています.googleは当初どう思っていましたか?
(4)アプリオブジェクトの作成
Application app = Instrumentation.newApplication(Application.class, context);
mAllApplications.add(app);
mInitialApplication = app;
app.onCreate();
ここは具体的に分かりませんでしたか?最初はよく分かりませんでしたが、全体の過程はいったい何をしていますか?全体的なものではなく、一部のcontext変数を表示します.このcontextを利用してinitを作って、initの時にLoadedAkに入ってきます.これはappkのすべての関連情報の集合です.なぜここに現れますか?このActivityThreadにおけるatch関数の本当の目的が完全に分かりました.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android" coreApp="true" android:sharedUserId="android.uid.system"
android:sharedUserLabel="@string/android_system_label">
上記のコードはAndroid Manifest.xmlの中の部分で、package nameは-->androidです.これで説明が通ります.ここで作成したアプリはこのアプリケーションです.一つのActivityThreadは複数のアプリを実行できます.ここのアプリはandroidです.そして、このandroidアプリはmInitialアプリアプリに設定されています.LoadedAnkの構造関数を振り返ってみます.
public LoadedApk(ActivityThread activityThread, String name,
Context systemContext, ApplicationInfo info, CompatibilityInfo compatInfo) {
mActivityThread = activityThread;
mApplicationInfo = info != null ? info : new ApplicationInfo();
mApplicationInfo.packageName = name;
mPackageName = name;
mAppDir = null;
mResDir = null;
mSharedLibraries = null;
mDataDir = null;
mDataDirFile = null;
mLibDir = null;
mBaseClassLoader = null;
mSecurityViolation = false;
mIncludeCode = true;
mClassLoader = systemContext.getClassLoader();
mResources = systemContext.getResources();
mDisplayAdjustments.setCompatibilityInfo(compatInfo);
}
とは、Androidというアプリを作成して、Aplication Infoを実際に例化して、mApple Info.package Nameを指定しました.mPackage Nameはすべてandroidです.一番重要なのはmClass Loader、mResource、mDisplayAdjustomentsです.このandroidアプリも彼のAndroid Manifest.xmlを提出しました.このAndroidアプリは一体何ですか?bingoとは、frame ework.ress.appkのことです.
(5)DropBox.set Report(new Drop BoxReport();
(6)View RootImpl.addConfigCallback(new ComponentCallbacks 2(){}
View RootImplにConfigrationChangedイベントを受信するために登録します.Windows Managerを紹介する時に、dispatchのような事件が具体的なactivityの中にあれば分析します.
4)ActivityThreadで分析した後、mSystemThread=at;ここのmSystemThreadとmSelfは全部staticです.
5)AMSを初期化するmContect、mFactoryTest、mIntent Firewall、mStock Supervisor
Context context = at.getSystemContext();
context.setTheme(android.R.style.Theme_Holo);
m.mContext = context;
m.mFactoryTest = factoryTest;
m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface());
m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper);
m.mBatteryStatsService.publish(context);
m.mUsageStatsService.publish(context);
m.mAppOpsService.publish(context);
Intent Firewallを主に作成し、Intent Firewallから/data/system/ifw/ifw.xml or /data/secure/system/ifw/xmlからactivity,broadcast,serviceを読み取り、ファイルの変更を常時傍受しています. ,Intent FirewallInterfaceはActivityManagerServiceのプロセスidかどうかです.次のBatteryStits Serviceは、UsageStatits Service、AppOpsServiceです.サービスをbinderに登録します. manager6)m.startRunning(null、null、null、null);
public final void startRunning(String pkg, String cls, String action,
String data) {
synchronized(this) {
if (mStartRunning) {
return;
}
mStartRunning = true;
mTopComponent = pkg != null && cls != null
? new ComponentName(pkg, cls) : null;
mTopAction = action != null ? action : Intent.ACTION_MAIN;
mTopData = data;
if (!mSystemReady) {
return;
}
}
systemReady(null);
}
startRunningに入る時mStartRunningとmSystemReadyは全部falseなので、ここではmStarrtRunningをtrueとし、mTopComponentをnullとし、mTopActをIntent.ACTIONとします.MAIN、mTopDataはnullで直接戻ります.ここまでActivityManager Service.mainは全部解析しました.
まとめてみます
mainのAThreadでlooperを作成し、AMS、つまりmSelfを実例化しました.次に、ActivityThreadというstaticのActivityThreadを実例化しました.つまり、mSystemThreadは、ActivityThreadの中でAppplicationを実行しました.frame ew-rek.appkです.続いていくつかの設定があります.mConteext、mFactoryTest、mIntent Firewall、mStockSupervisor、mBatteryStats Service、mUsageStats Service、mAppOppServiceなどです.スターリング.