安卓高手之路之ClassLoader(四)
安卓高手之路之ClassLoader(四) - 修补C++ - ITeye技术网站
显然,应用层的classLoader绝对不仅仅是一个systemclassloader那么简单。那么他一定是与PackageInfo连接起来的。而这个连接的纽带就是ContextImpl。ContextImpl又与apk一一对应。
- @Override
- public ClassLoader getClassLoader() {
- return mPackageInfo != null ?
- mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
- }
@Override public ClassLoader getClassLoader() { return mPackageInfo != null ? mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader(); }
- public ClassLoader getClassLoader() {
- synchronized (this) {
- if (mClassLoader != null) {
- return mClassLoader;
- }
- if (mIncludeCode && !mPackageName.equals("android")) {
- String zip = mAppDir;
- /*
- * The following is a bit of a hack to inject
- * instrumentation into the system: If the app
- * being started matches one of the instrumentation names,
- * then we combine both the "instrumentation" and
- * "instrumented" app into the path, along with the
- * concatenation of both apps‘ shared library lists.
- */
- String instrumentationAppDir =
- mActivityThread.mInstrumentationAppDir;
- String instrumentationAppPackage =
- mActivityThread.mInstrumentationAppPackage;
- String instrumentedAppDir =
- mActivityThread.mInstrumentedAppDir;
- String[] instrumentationLibs = null;
- if (mAppDir.equals(instrumentationAppDir)
- || mAppDir.equals(instrumentedAppDir)) {
- zip = instrumentationAppDir + ":" + instrumentedAppDir;
- if (! instrumentedAppDir.equals(instrumentationAppDir)) {
- instrumentationLibs =
- getLibrariesFor(instrumentationAppPackage);
- }
- }
- if ((mSharedLibraries != null) ||
- (instrumentationLibs != null)) {
- zip =
- combineLibs(mSharedLibraries, instrumentationLibs)
- + ‘:‘ + zip;
- }
- /*
- * With all the combination done (if necessary, actually
- * create the class loader.
- */
- if (ActivityThread.localLOGV)
- Slog.v(ActivityThread.TAG, "Class path: " + zip + ", JNI path: " + mLibDir);
- // Temporarily disable logging of disk reads on the Looper thread
- // as this is early and necessary.
- StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
- mClassLoader =
- ApplicationLoaders.getDefault().getClassLoader(
- zip, mLibDir, mBaseClassLoader);
- initializeJavaContextClassLoader();
- StrictMode.setThreadPolicy(oldPolicy);
- } else {
- if (mBaseClassLoader == null) {
- mClassLoader = ClassLoader.getSystemClassLoader();
- } else {
- mClassLoader = mBaseClassLoader;
- }
- }
- return mClassLoader;
- }
- }
public ClassLoader getClassLoader() { synchronized (this) { if (mClassLoader != null) { return mClassLoader; } if (mIncludeCode && !mPackageName.equals("android")) { String zip = mAppDir; /* * The following is a bit of a hack to inject * instrumentation into the system: If the app * being started matches one of the instrumentation names, * then we combine both the "instrumentation" and * "instrumented" app into the path, along with the * concatenation of both apps‘ shared library lists. */ String instrumentationAppDir = mActivityThread.mInstrumentationAppDir; String instrumentationAppPackage = mActivityThread.mInstrumentationAppPackage; String instrumentedAppDir = mActivityThread.mInstrumentedAppDir; String[] instrumentationLibs = null; if (mAppDir.equals(instrumentationAppDir) || mAppDir.equals(instrumentedAppDir)) { zip = instrumentationAppDir + ":" + instrumentedAppDir; if (! instrumentedAppDir.equals(instrumentationAppDir)) { instrumentationLibs = getLibrariesFor(instrumentationAppPackage); } } if ((mSharedLibraries != null) || (instrumentationLibs != null)) { zip = combineLibs(mSharedLibraries, instrumentationLibs) + ‘:‘ + zip; } /* * With all the combination done (if necessary, actually * create the class loader. */ if (ActivityThread.localLOGV) Slog.v(ActivityThread.TAG, "Class path: " + zip + ", JNI path: " + mLibDir); // Temporarily disable logging of disk reads on the Looper thread // as this is early and necessary. StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); mClassLoader = ApplicationLoaders.getDefault().getClassLoader( zip, mLibDir, mBaseClassLoader); initializeJavaContextClassLoader(); StrictMode.setThreadPolicy(oldPolicy); } else { if (mBaseClassLoader == null) { mClassLoader = ClassLoader.getSystemClassLoader(); } else { mClassLoader = mBaseClassLoader; } } return mClassLoader; } }
- mClassLoader =
- ApplicationLoaders.getDefault().getClassLoader(
- zip, mLibDir, mBaseClassLoader);
mClassLoader = ApplicationLoaders.getDefault().getClassLoader( zip, mLibDir, mBaseClassLoader);
- /*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package android.app;
- import dalvik.system.PathClassLoader;
- import java.util.HashMap;
- import java.util.Map;
- class ApplicationLoaders
- {
- public static ApplicationLoaders getDefault()
- {
- return gApplicationLoaders;
- }
- public ClassLoader getClassLoader(String zip, String libPath, ClassLoader parent)
- {
- /*
- * This is the parent we use if they pass "null" in. In theory
- * this should be the "system" class loader; in practice we
- * don‘t use that and can happily (and more efficiently) use the
- * bootstrap class loader.
- */
- ClassLoader baseParent = ClassLoader.getSystemClassLoader().getParent();
- synchronized (mLoaders) {
- if (parent == null) {
- parent = baseParent;
- }
- /*
- * If we‘re one step up from the base class loader, find
- * something in our cache. Otherwise, we create a whole
- * new ClassLoader for the zip archive.
- */
- if (parent == baseParent) {
- ClassLoader loader = mLoaders.get(zip);
- if (loader != null) {
- return loader;
- }
- PathClassLoader pathClassloader =
- new PathClassLoader(zip, libPath, parent);
- mLoaders.put(zip, pathClassloader);
- return pathClassloader;
- }
- return new PathClassLoader(zip, parent);
- }
- }
- private final Map<String, ClassLoader> mLoaders = new HashMap<String, ClassLoader>();
- private static final ApplicationLoaders gApplicationLoaders
- = new ApplicationLoaders();
- }
/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app; import dalvik.system.PathClassLoader; import java.util.HashMap; import java.util.Map; class ApplicationLoaders { public static ApplicationLoaders getDefault() { return gApplicationLoaders; } public ClassLoader getClassLoader(String zip, String libPath, ClassLoader parent) { /* * This is the parent we use if they pass "null" in. In theory * this should be the "system" class loader; in practice we * don‘t use that and can happily (and more efficiently) use the * bootstrap class loader. */ ClassLoader baseParent = ClassLoader.getSystemClassLoader().getParent(); synchronized (mLoaders) { if (parent == null) { parent = baseParent; } /* * If we‘re one step up from the base class loader, find * something in our cache. Otherwise, we create a whole * new ClassLoader for the zip archive. */ if (parent == baseParent) { ClassLoader loader = mLoaders.get(zip); if (loader != null) { return loader; } PathClassLoader pathClassloader = new PathClassLoader(zip, libPath, parent); mLoaders.put(zip, pathClassloader); return pathClassloader; } return new PathClassLoader(zip, parent); } } private final Map<String, ClassLoader> mLoaders = new HashMap<String, ClassLoader>(); private static final ApplicationLoaders gApplicationLoaders = new ApplicationLoaders(); }
所有的东西都在这里。具体不多说了。看了就明白。
还有一个活动当前调用的classLoader。如下:
- static void Dalvik_dalvik_system_VMStack_getCallingClassLoader(const u4* args,
- JValue* pResult)
- {
- ClassObject* clazz =
- dvmGetCaller2Class(dvmThreadSelf()->interpSave.curFrame);
- UNUSED_PARAMETER(args);
- if (clazz == NULL)
- RETURN_PTR(NULL);
- RETURN_PTR(clazz->classLoader);
- }
static void Dalvik_dalvik_system_VMStack_getCallingClassLoader(const u4* args, JValue* pResult) { ClassObject* clazz = dvmGetCaller2Class(dvmThreadSelf()->interpSave.curFrame); UNUSED_PARAMETER(args); if (clazz == NULL) RETURN_PTR(NULL); RETURN_PTR(clazz->classLoader); }java层为VMStack.java
- native public static ClassLoader getCallingClassLoader();
native public static ClassLoader getCallingClassLoader();可以直接认为是加载当前类的classLoader。如果是BootClassLoader,那么就返回null
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。