- public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags, DatabaseErrorHandler errorHandler) {
- SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler);
- db.open();
- return db;
- }
很多童鞋在追踪API源码的时候都会发现Activity类下的openOrCreateDatabase方法会指向ContextWrapper类下的openOrCreateDatabase方法:
- @Override
- public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
- return mBase.openOrCreateDatabase(name, mode, factory);
- }
- public abstract SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory);
大家知道Context作为Android的上下文环境引用抽象类对我们来说既熟悉又陌生,熟悉在于我们经常会使用到它,Android呢也有很多它的扩展类,陌生在于我们不知道本质是什么或者说其到底是个什么东西?关于Context的相关知识大家可以百度谷歌下,这方面的相关文档很多,在这里就不作过多介绍了,阅读本文你不需要知道过多的Context知识。
为了搞清楚ContextWrapper在构造函数中传入的Context引用我们回到Activity类中,Activity是ContextThemeWrapper扩展类,而ContextThemeWrapper类又扩展至ContextWrapper,在ContextThemeWrapper类中同样有一个名为mBase的Context成员变量,其被赋值的地方有两处:
第一处:构造函数
- public ContextThemeWrapper(Context base, int themeres) {
- super(base);
- mBase = base;
- mThemeResource = themeres;
- }
- @Override
- protected void attachBaseContext(Context newBase) {
- super.attachBaseContext(newBase);
- mBase = newBase;
- }
- final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token, int ident, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, NonConfigurationInstances lastNonConfigurationInstances, Configuration config) {
- attachBaseContext(context);
- // 省去无关代码……………………
- }
我们知道一个Android应用会有一个Activity作为程序启动时显示的主界面,而这个Activity我们会在AndroidManifest.xml文件中通过intent-filter来定义:
- <activity
- android:name="com.aigestudio.MainActivity"
- android:label="@string/app_name" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- public final class ActivityThread {
- // 省略无数代码……………………
- public static void main(String[] args) {
- SamplingProfilerIntegration.start();
- CloseGuard.setEnabled(false);
- Environment.initForCurrentUser();
- EventLogger.setReporter(new EventLoggingReporter());
- Security.addProvider(new AndroidKeyStoreProvider());
- Process.setArgV0("<pre-initialized>");
- Looper.prepareMainLooper();
- <strong>ActivityThread thread = new ActivityThread();
- thread.attach(false);
- if (sMainThreadHandler == null) {
- sMainThreadHandler = thread.getHandler();
- }</strong>
- AsyncTask.init();
- if (false) {
- Looper.myLooper().setMessageLogging(new
- LogPrinter(Log.DEBUG, "ActivityThread"));
- }
- Looper.loop();
- throw new RuntimeException("Main thread loop unexpectedly exited");
- }
- }
- ActivityThread thread = new ActivityThread();
- // 省略一行代码……………………
- if (sMainThreadHandler == null) {
- sMainThreadHandler = thread.getHandler();
- }
- static Handler sMainThreadHandler;
- sMainThreadHandler = thread.getHandler();
- final Handler getHandler() {
- return mH;
- }
- final H mH = new H();
- private class H extends Handler {
- // 省去大量代码……………………
- public void handleMessage(Message msg) {
- if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
- switch (msg.what) {
- case LAUNCH_ACTIVITY: {
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
- ActivityClientRecord r = (ActivityClientRecord)msg.obj;
- r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);
- handleLaunchActivity(r, null);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- } break;
- // 省去大量代码……………………
- }
- // 省去一行代码……………………
- }
- // 省去大量代码……………………
- }
- private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
- // 省去一些代码……………………
- Activity a = performLaunchActivity(r, customIntent);
- // 省去一群代码……………………
- }
- private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
- ActivityInfo aInfo = r.activityInfo;
- if (r.packageInfo == null) {
- r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE);
- }
- ComponentName component = r.intent.getComponent();
- if (component == null) {
- component = r.intent.resolveActivity(mInitialApplication.getPackageManager());
- r.intent.setComponent(component);
- }
- if (r.activityInfo.targetActivity != null) {
- component = new ComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity);
- }
- Activity activity = null;
- try {
- java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
- activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
- StrictMode.incrementExpectedActivityCount(activity.getClass());
- r.intent.setExtrasClassLoader(cl);
- if (r.state != null) {
- r.state.setClassLoader(cl);
- }
- } catch (Exception e) {
- if (!mInstrumentation.onException(activity, e)) {
- throw new RuntimeException("Unable to instantiate activity " + component + ": " + e.toString(), e);
- }
- }
- try {
- Application app = r.packageInfo.makeApplication(false, mInstrumentation);
- if (localLOGV)
- Slog.v(TAG, "Performing launch of " + r);
- if (localLOGV)
- Slog.v(TAG, r + ": app=" + app + ", appName=" + app.getPackageName() + ", pkg=" + r.packageInfo.getPackageName() + ", comp=" + r.intent.getComponent().toShortString() + ", dir=" + r.packageInfo.getAppDir());
- if (activity != null) {
- Context appContext = createBaseContextForActivity(r, activity);
- CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
- Configuration config = new Configuration(mCompatConfiguration);
- if (DEBUG_CONFIGURATION)
- Slog.v(TAG, "Launching activity " + r.activityInfo.name + " with config " + config);
- activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config);
- if (customIntent != null) {
- activity.mIntent = customIntent;
- }
- r.lastNonConfigurationInstances = null;
- activity.mStartedActivity = false;
- int theme = r.activityInfo.getThemeResource();
- if (theme != 0) {
- activity.setTheme(theme);
- }
- activity.mCalled = false;
- mInstrumentation.callActivityOnCreate(activity, r.state);
- if (!activity.mCalled) {
- throw new SuperNotCalledException("Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onCreate()");
- }
- r.activity = activity;
- r.stopped = true;
- if (!r.activity.mFinished) {
- activity.performStart();
- r.stopped = false;
- }
- if (!r.activity.mFinished) {
- if (r.state != null) {
- mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
- }
- }
- if (!r.activity.mFinished) {
- activity.mCalled = false;
- mInstrumentation.callActivityOnPostCreate(activity, r.state);
- if (!activity.mCalled) {
- throw new SuperNotCalledException("Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onPostCreate()");
- }
- }
- }
- r.paused = true;
- mActivities.put(r.token, r);
- } catch (SuperNotCalledException e) {
- throw e;
- } catch (Exception e) {
- if (!mInstrumentation.onException(activity, e)) {
- throw new RuntimeException("Unable to start activity " + component + ": " + e.toString(), e);
- }
- }
- return activity;
- }
- activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
- Context appContext = createBaseContextForActivity(r, activity);
- // 省去若干代码
- activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config);
- private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
- ContextImpl appContext = new ContextImpl();
- appContext.init(r.packageInfo, r.token, this);
- appContext.setOuterContext(activity);
- Context baseContext = appContext;
- // 省略一段代码……………………
- return baseContext;
- }
- @Override
- public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory, DatabaseErrorHandler errorHandler) {
- File f = validateFilePath(name, true);
- int flags = SQLiteDatabase.CREATE_IF_NECESSARY;
- if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) {
- flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING;
- }
- SQLiteDatabase db = SQLiteDatabase.openDatabase(f.getPath(), factory, flags, errorHandler);
- setFilePermissionsFromMode(f.getPath(), mode, 0);
- return db;
- }
关于ContextImpl的内容很丰富,其内部代码就有两千行之巨,但是它依然是个轻量级的类,因为其大多数操作都是直接调用PackageInfo的方法来进行的,有机会可以对其再做更深的探讨,这篇文章呢就到此为止!虽说篇幅很长问题其实很简单,但是追求真理的道路我们不能停啊~同时……药不能停……Fuck!
转自http://blog.csdn.net/aigestudio/article/details/39029085