in robolectric/src/main/java/org/robolectric/android/internal/ParallelUniverse.java [97:239]
public void setUpApplicationState(ApkLoader apkLoader, Method method,
Configuration configuration, AndroidManifest appManifest, SdkEnvironment sdkEnvironment) {
Config config = configuration.get(Config.class);
ConfigurationRegistry.instance = new ConfigurationRegistry(configuration);
ReflectionHelpers.setStaticField(RuntimeEnvironment.class, "apiLevel", apiLevel);
RuntimeEnvironment.application = null;
RuntimeEnvironment.setActivityThread(null);
RuntimeEnvironment.setTempDirectory(new TempDirectory(createTestDataDirRootPath(method)));
RuntimeEnvironment.setMasterScheduler(new Scheduler());
RuntimeEnvironment.setMainThread(Thread.currentThread());
if (!loggingInitialized) {
ShadowLog.setupLogging();
loggingInitialized = true;
}
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
Security.insertProviderAt(new BouncyCastleProvider(), 1);
}
android.content.res.Configuration androidConfiguration =
new android.content.res.Configuration();
DisplayMetrics displayMetrics = new DisplayMetrics();
Bootstrap.applyQualifiers(config.qualifiers(), apiLevel, androidConfiguration,
displayMetrics);
Locale locale = apiLevel >= VERSION_CODES.N
? androidConfiguration.getLocales().get(0)
: androidConfiguration.locale;
Locale.setDefault(locale);
// Looper needs to be prepared before the activity thread is created
if (Looper.myLooper() == null) {
Looper.prepareMainLooper();
}
ShadowLooper.getShadowMainLooper().resetScheduler();
final ActivityThread activityThread = ReflectionHelpers.newInstance(ActivityThread.class);
RuntimeEnvironment.setActivityThread(activityThread);
final _ActivityThread_ _activityThread_ = reflector(_ActivityThread_.class, activityThread);
Package parsedPackage = loadAppPackage(apkLoader, config, appManifest, sdkEnvironment);
ApplicationInfo applicationInfo = parsedPackage.applicationInfo;
// unclear why, but prior to P the processName wasn't set
if (apiLevel < P && applicationInfo.processName == null) {
applicationInfo.processName = parsedPackage.packageName;
}
setUpPackageStorage(applicationInfo, parsedPackage);
// Bit of a hack... Context.createPackageContext() is called before the application is created.
// It calls through
// to ActivityThread for the package which in turn calls the PackageManagerService directly.
// This works for now
// but it might be nicer to have ShadowPackageManager implementation move into the service as
// there is also lots of
// code in there that can be reusable, e.g: the XxxxIntentResolver code.
ShadowActivityThread.setApplicationInfo(applicationInfo);
_activityThread_.setCompatConfiguration(androidConfiguration);
ReflectionHelpers
.setStaticField(ActivityThread.class, "sMainThreadHandler", new Handler(Looper.myLooper()));
Bootstrap.setUpDisplay(androidConfiguration, displayMetrics);
activityThread.applyConfigurationToResources(androidConfiguration);
Resources systemResources = Resources.getSystem();
systemResources.updateConfiguration(androidConfiguration, displayMetrics);
Context systemContextImpl = reflector(_ContextImpl_.class).createSystemContext(activityThread);
RuntimeEnvironment.systemContext = systemContextImpl;
Application application = createApplication(appManifest, config);
RuntimeEnvironment.application = application;
Instrumentation instrumentation =
createInstrumentation(activityThread, applicationInfo, application);
if (application != null) {
final Class<?> appBindDataClass;
try {
appBindDataClass = Class.forName("android.app.ActivityThread$AppBindData");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
final Object appBindData = ReflectionHelpers.newInstance(appBindDataClass);
final _AppBindData_ _appBindData_ = reflector(_AppBindData_.class, appBindData);
_appBindData_.setProcessName(parsedPackage.packageName);
_appBindData_.setAppInfo(applicationInfo);
_activityThread_.setBoundApplication(appBindData);
final LoadedApk loadedApk =
activityThread.getPackageInfo(applicationInfo, null, Context.CONTEXT_INCLUDE_CODE);
final _LoadedApk_ _loadedApk_ = reflector(_LoadedApk_.class, loadedApk);
Context contextImpl;
if (apiLevel >= VERSION_CODES.LOLLIPOP) {
contextImpl = reflector(_ContextImpl_.class).createAppContext(activityThread, loadedApk);
} else {
try {
contextImpl =
systemContextImpl.createPackageContext(
applicationInfo.packageName, Context.CONTEXT_INCLUDE_CODE);
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(e);
}
}
ShadowPackageManager shadowPackageManager = Shadow.extract(contextImpl.getPackageManager());
shadowPackageManager.addPackageInternal(parsedPackage);
_activityThread_.setInitialApplication(application);
ShadowApplication shadowApplication = Shadow.extract(application);
shadowApplication.callAttach(contextImpl);
reflector(_ContextImpl_.class, contextImpl).setOuterContext(application);
Secure.setLocationProviderEnabled(application.getContentResolver(), GPS_PROVIDER, true);
Resources appResources = application.getResources();
_loadedApk_.setResources(appResources);
_loadedApk_.setApplication(application);
if (RuntimeEnvironment.getApiLevel() >= VERSION_CODES.O) {
// Preload fonts resources
FontsContract.setApplicationContextForResources(application);
}
registerBroadcastReceivers(application, appManifest);
appResources.updateConfiguration(androidConfiguration, displayMetrics);
if (ShadowAssetManager.useLegacy()) {
populateAssetPaths(appResources.getAssets(), appManifest);
}
instrumentation.onCreate(new Bundle());
PerfStatsCollector.getInstance()
.measure("application onCreate()", () -> application.onCreate());
}
}