android+程序入口+调用,Android应用开发之程序在系统中如何完成启动?

本文将带你了解Android应用开发Android开发之程序在系统中如何完成启动?,希望本文对大家学Android有所帮助。

一段程序的调用都有它的程序入口,众所周知Java程序的入口在main方法。作为Android来说应用程序的启动是通过 ActivityThread 类 来执行的。系统中对于该类的介绍如下:

该类是管理应用程序进程中主线程的执行,调度和执行活动,广播以及活动管理者请求的其他操作。

当我打开App时,首先调用的是这个类中的main方法,也就是说这里控制着程序的启动。

ActivityThread#main

public static void main(String[] args) {

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");

SamplingProfilerIntegration.start();

// CloseGuard defaults to true and can be quite spammy.  We

// disable it here, but selectively enable it later (via

// StrictMode) on debug builds, but using DropBox, not logs.

CloseGuard.setEnabled(false);

//初始化当前的可访问环境,主要是系统内部的可存储环境

Environment.initForCurrentUser();

// Set the reporter for event logging in libcore

EventLogger.setReporter(new EventLoggingReporter());

// Make sure TrustedCertificateStore looks in the right place for CA certificates

final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());

TrustedCertificateStore.setDefaultUserDirectory(configDir);

Process.setArgV0("");

//step 1:

Looper.prepareMainLooper();

//step 2:

ActivityThread thread = new ActivityThread();

thread.attach(false);

//初始化一个线程安全的handler对象

if (sMainThreadHandler == null) {

sMainThreadHandler = thread.getHandler();

}

if (false) {

Looper.myLooper().setMessageLogging(new

LogPrinter(Log.DEBUG, "ActivityThread"));

}

// End of event ActivityThreadMain.

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

//执行消息队列,不断轮询消息。

Looper.loop();

throw new RuntimeException("Main thread loop unexpectedly exited");

}

main方法中重要的操作:

step 1:

Looper.prepareMainLooper() :初始化当前的线程作为一个looper,并且标记为应用中的main looper。后面还跟着对应的loop(),在消息队列中轮询接收的消息。

step 2:

实例化当前ActivityThread对象,并且调用attach。继续分析该方法中的调用。

ActivityThread#attach

private void attach(boolean system) {

sCurrentActivityThread = this;

mSystemThread = system;

if (!system) {

ViewRootImpl.addFirstDrawHandler(new Runnable() {

@Override

public void run() {

ensureJitEnabled();

}

});

android.ddm.DdmHandleAppName.setAppName("",

UserHandle.myUserId());

RuntimeInit.setApplicationObject(mAppThread.asBinder());

//step 1: 将ActivityManagerService 和 ApplicationThread 关联起来

final IActivityManager mgr = ActivityManager.getService();

try {

mgr.attachApplication(mAppThread);

} catch (RemoteException ex) {

throw ex.rethrowFromSystemServer();

}

// Watch for getting close to heap limit.

BinderInternal.addGcWatcher(new Runnable() {

@Override public void run() {

if (!mSomeActivitiesChanged) {

return;

}

Runtime runtime = Runtime.getRuntime();

long dalvikMax = runtime.maxMemory();

long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();

if (dalvikUsed > ((3*dalvikMax)/4)) {

if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)

+ " total=" + (runtime.totalMemory()/1024)

+ " used=" + (dalvikUsed/1024));

mSomeActivitiesChanged = false;

try {

mgr.releaseSomeActivities(mAppThread);

} catch (RemoteException e) {

throw e.rethrowFromSystemServer();

}

}

}

});

} 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 = ContextImpl.createAppContext(

this, getSystemContext().mPackageInfo);

mInitialApplication = context.mPackageInfo.makeApplication(true, null);

mInitialApplication.onCreate();

} catch (Exception e) {

throw new RuntimeException(

"Unable to instantiate Application():" + e.toString(), e);

}

}

// add dropbox logging to libcore

DropBox.setReporter(new DropBoxReporter());

ViewRootImpl.ConfigChangedCallback configChangedCallback

= (Configuration globalConfig) -> {

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(globalConfig,

null /* compat */)) {

updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),

mResourcesManager.getConfiguration().getLocales());

// This actually changed the resources! Tell everyone about it.

if (mPendingConfiguration == null

|| mPendingConfiguration.isOtherSeqNewer(globalConfig)) {

mPendingConfiguration = globalConfig;

sendMessage(H.CONFIGURATION_CHANGED, globalConfig);

}

}

}

};

// 添加配置信息接口回调

ViewRootImpl.addConfigCallback(configChangedCallback);

}

上面方法中传入的参数为false,所以执行的是if中的逻辑。这里面主要的操作就是通过ActivityManager.getService() 返回了ActivityManagerService对象,然后调用attachApplication方法将ApplicationThread 对象关联。下面我们继续进入attachApplication 方法来分析。

ActivityManagerService#attachApplication

@Override

public final void attachApplication(IApplicationThread thread) {

synchronized (this) {

int callingPid = Binder.getCallingPid();

final long origId = Binder.clearCallingIdentity();

attachApplicationLocked(thread, callingPid);

Binder.restoreCallingIdentity(origId);

}

}

ActivityManagerService#attachApplicationLocked

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值