溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Android中Context的作用是什么

發(fā)布時(shí)間:2021-06-25 14:27:03 來(lái)源:億速云 閱讀:318 作者:Leah 欄目:移動(dòng)開(kāi)發(fā)

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)Android中Context的作用是什么,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

Context基本概念

Context是什么?

1) Context是一個(gè)抽象類,其通用實(shí)現(xiàn)在ContextImpl類中。

2) Context:是一個(gè)訪問(wèn)application環(huán)境全局信息的接口,通過(guò)它可以訪問(wèn)application的資源和相關(guān)的類,其主要功能如下:

啟動(dòng)Activity
啟動(dòng)和停止Service
發(fā)送廣播消息(Intent)
注冊(cè)廣播消息(Intent)接收者
可以訪問(wèn)APK中各種資源(如Resources和AssetManager等)
可以訪問(wèn)Package的相關(guān)信息
APK的各種權(quán)限管理

從以上分析可以看出,Context就是一個(gè)對(duì)APK包無(wú)所不知的大管家,大家需要什么,直接問(wèn)它就可以了。

Context與View的關(guān)系

View與Context(或Activity)的關(guān)系類似于明星與經(jīng)紀(jì)人的關(guān)系,所以創(chuàng)建View時(shí),必須明確指定其Context(即經(jīng)紀(jì)人或大管家),否則View就成不了明星。

Context家族關(guān)系

Android中Context的作用是什么

Context關(guān)鍵函數(shù)

public abstract class Context {      // 獲取應(yīng)用程序包的AssetManager實(shí)例     public abstract AssetManager getAssets();       // 獲取應(yīng)用程序包的Resources實(shí)例     public abstract Resources getResources();      // 獲取PackageManager實(shí)例,以查看全局package信息         public abstract PackageManager getPackageManager();      // 獲取應(yīng)用程序包的ContentResolver實(shí)例     public abstract ContentResolver getContentResolver();          // 它返回當(dāng)前進(jìn)程的主線程的Looper,此線程分發(fā)調(diào)用給應(yīng)用組件(activities, services等)     public abstract Looper getMainLooper();      // 返回當(dāng)前進(jìn)程的單實(shí)例全局Application對(duì)象的Context          public abstract Context getApplicationContext();      // 從string表中獲取本地化的、格式化的字符序列     public final CharSequence getText(int resId) {         return getResources().getText(resId);     }      // 從string表中獲取本地化的字符串     public final String getString(int resId) {         return getResources().getString(resId);     }      public final String getString(int resId, Object... formatArgs) {         return getResources().getString(resId, formatArgs);     }      // 返回一個(gè)可用于獲取包中類信息的class loader     public abstract ClassLoader getClassLoader();      // 返回應(yīng)用程序包名     public abstract String getPackageName();      // 返回應(yīng)用程序信息     public abstract ApplicationInfo getApplicationInfo();      // 根據(jù)文件名獲取SharedPreferences     public abstract SharedPreferences getSharedPreferences(String name,             int mode);      // 其根目錄為: Environment.getExternalStorageDirectory()     /*      * @param type The type of files directory to return.  May be null for      * the root of the files directory or one of      * the following Environment constants for a subdirectory:      * {@link android.os.Environment#DIRECTORY_MUSIC},      * {@link android.os.Environment#DIRECTORY_PODCASTS},      * {@link android.os.Environment#DIRECTORY_RINGTONES},      * {@link android.os.Environment#DIRECTORY_ALARMS},      * {@link android.os.Environment#DIRECTORY_NOTIFICATIONS},      * {@link android.os.Environment#DIRECTORY_PICTURES}, or      * {@link android.os.Environment#DIRECTORY_MOVIES}.         */     public abstract File getExternalFilesDir(String type);      // 返回應(yīng)用程序obb文件路徑     public abstract File getObbDir();      // 啟動(dòng)一個(gè)新的activity      public abstract void startActivity(Intent intent);      // 啟動(dòng)一個(gè)新的activity      public void startActivityAsUser(Intent intent, UserHandle user) {         throw new RuntimeException("Not implemented. Must override in a subclass.");     }      // 啟動(dòng)一個(gè)新的activity      // intent: 將被啟動(dòng)的activity的描述信息     // options: 描述activity將如何被啟動(dòng)     public abstract void startActivity(Intent intent, Bundle options);      // 啟動(dòng)多個(gè)新的activity     public abstract void startActivities(Intent[] intents);      // 啟動(dòng)多個(gè)新的activity     public abstract void startActivities(Intent[] intents, Bundle options);      // 廣播一個(gè)intent給所有感興趣的接收者,異步機(jī)制      public abstract void sendBroadcast(Intent intent);      // 廣播一個(gè)intent給所有感興趣的接收者,異步機(jī)制      public abstract void sendBroadcast(Intent intent,String receiverPermission);      public abstract void sendOrderedBroadcast(Intent intent,String receiverPermission);       public abstract void sendOrderedBroadcast(Intent intent,             String receiverPermission, BroadcastReceiver resultReceiver,             Handler scheduler, int initialCode, String initialData,             Bundle initialExtras);      public abstract void sendBroadcastAsUser(Intent intent, UserHandle user);      public abstract void sendBroadcastAsUser(Intent intent, UserHandle user,             String receiverPermission);        // 注冊(cè)一個(gè)BroadcastReceiver,且它將在主activity線程中運(yùn)行     public abstract Intent registerReceiver(BroadcastReceiver receiver,                                             IntentFilter filter);      public abstract Intent registerReceiver(BroadcastReceiver receiver,             IntentFilter filter, String broadcastPermission, Handler scheduler);      public abstract void unregisterReceiver(BroadcastReceiver receiver);       // 請(qǐng)求啟動(dòng)一個(gè)application service     public abstract ComponentName startService(Intent service);      // 請(qǐng)求停止一個(gè)application service     public abstract boolean stopService(Intent service);       // 連接一個(gè)應(yīng)用服務(wù),它定義了application和service間的依賴關(guān)系     public abstract boolean bindService(Intent service, ServiceConnection conn,             int flags);      // 斷開(kāi)一個(gè)應(yīng)用服務(wù),當(dāng)服務(wù)重新開(kāi)始時(shí),將不再接收到調(diào)用,      // 且服務(wù)允許隨時(shí)停止     public abstract void unbindService(ServiceConnection conn);        // 返回系統(tǒng)級(jí)service句柄     /*      * @see #WINDOW_SERVICE      * @see android.view.WindowManager      * @see #LAYOUT_INFLATER_SERVICE      * @see android.view.LayoutInflater      * @see #ACTIVITY_SERVICE      * @see android.app.ActivityManager      * @see #POWER_SERVICE      * @see android.os.PowerManager      * @see #ALARM_SERVICE      * @see android.app.AlarmManager      * @see #NOTIFICATION_SERVICE      * @see android.app.NotificationManager      * @see #KEYGUARD_SERVICE      * @see android.app.KeyguardManager      * @see #LOCATION_SERVICE      * @see android.location.LocationManager      * @see #SEARCH_SERVICE      * @see android.app.SearchManager      * @see #SENSOR_SERVICE      * @see android.hardware.SensorManager      * @see #STORAGE_SERVICE      * @see android.os.storage.StorageManager      * @see #VIBRATOR_SERVICE      * @see android.os.Vibrator      * @see #CONNECTIVITY_SERVICE      * @see android.net.ConnectivityManager      * @see #WIFI_SERVICE      * @see android.net.wifi.WifiManager      * @see #AUDIO_SERVICE      * @see android.media.AudioManager      * @see #MEDIA_ROUTER_SERVICE      * @see android.media.MediaRouter      * @see #TELEPHONY_SERVICE      * @see android.telephony.TelephonyManager      * @see #INPUT_METHOD_SERVICE      * @see android.view.inputmethod.InputMethodManager      * @see #UI_MODE_SERVICE      * @see android.app.UiModeManager      * @see #DOWNLOAD_SERVICE      * @see android.app.DownloadManager      */     public abstract Object getSystemService(String name);       public abstract int checkPermission(String permission, int pid, int uid);       // 返回一個(gè)新的與application name對(duì)應(yīng)的Context對(duì)象     public abstract Context createPackageContext(String packageName,             int flags) throws PackageManager.NameNotFoundException;          // 返回基于當(dāng)前Context對(duì)象的新對(duì)象,其資源與display相匹配     public abstract Context createDisplayContext(Display display);  }

ContextImpl關(guān)鍵成員和函數(shù)

/**  * Common implementation of Context API, which provides the base  * context object for Activity and other application components.  */ class ContextImpl extends Context {     private final static String TAG = "ContextImpl";     private final static boolean DEBUG = false;      private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =             new HashMap<String, SharedPreferencesImpl>();      /*package*/ LoadedApk mPackageInfo; // 關(guān)鍵數(shù)據(jù)成員     private String mBasePackageName;     private Resources mResources;     /*package*/ ActivityThread mMainThread; // 主線程      @Override     public AssetManager getAssets() {         return getResources().getAssets();     }      @Override     public Looper getMainLooper() {         return mMainThread.getLooper();     }      @Override     public Object getSystemService(String name) {         ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);         return fetcher == null ? null : fetcher.getService(this);     }      @Override     public void startActivity(Intent intent, Bundle options) {         warnIfCallingFromSystemProcess();         if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {             throw new AndroidRuntimeException(                     "Calling startActivity() from outside of an Activity "                     + " context requires the FLAG_ACTIVITY_NEW_TASK flag."                     + " Is this really what you want?");         }         mMainThread.getInstrumentation().execStartActivity(             getOuterContext(), mMainThread.getApplicationThread(), null,             (Activity)null, intent, -1, options);     } }

ContextWrapper

它只是對(duì)Context類的一種封裝,它的構(gòu)造函數(shù)包含了一個(gè)真正的Context引用,即ContextImpl對(duì)象。

/**  * Proxying implementation of Context that simply delegates all of its calls to  * another Context.  Can be subclassed to modify behavior without changing  * the original Context.  */ public class ContextWrapper extends Context {     Context mBase; //該屬性指向一個(gè)ContextIml實(shí)例      public ContextWrapper(Context base) {         mBase = base;     }      /**      * Set the base context for this ContextWrapper.  All calls will then be      * delegated to the base context.  Throws      * IllegalStateException if a base context has already been set.      *       * @param base The new base context for this wrapper.      * 創(chuàng)建Application、Service、Activity,會(huì)調(diào)用該方法給mBase屬性賦值      */     protected void attachBaseContext(Context base) {         if (mBase != null) {             throw new IllegalStateException("Base context already set");         }         mBase = base;     }      @Override     public Looper getMainLooper() {         return mBase.getMainLooper();     }      @Override     public Object getSystemService(String name) {         return mBase.getSystemService(name);     }      @Override     public void startActivity(Intent intent) {         mBase.startActivity(intent);     } }

ContextThemeWrapper

該類內(nèi)部包含了主題(Theme)相關(guān)的接口,即android:theme屬性指定的。只有Activity需要主題,Service不需要主題,所以Service直接繼承于ContextWrapper類。

/**  * A ContextWrapper that allows you to modify the theme from what is in the   * wrapped context.   */ public class ContextThemeWrapper extends ContextWrapper {     private Context mBase;     private int mThemeResource;     private Resources.Theme mTheme;     private LayoutInflater mInflater;     private Configuration mOverrideConfiguration;     private Resources mResources;      public ContextThemeWrapper() {         super(null);     }          public ContextThemeWrapper(Context base, int themeres) {         super(base);         mBase = base;         mThemeResource = themeres;     }      @Override protected void attachBaseContext(Context newBase) {         super.attachBaseContext(newBase);         mBase = newBase;     }      @Override public void setTheme(int resid) {         mThemeResource = resid;         initializeTheme();     }      @Override public Resources.Theme getTheme() {         if (mTheme != null) {             return mTheme;         }          mThemeResource = Resources.selectDefaultTheme(mThemeResource,                 getApplicationInfo().targetSdkVersion);         initializeTheme();          return mTheme;     } }

何時(shí)創(chuàng)建Context

應(yīng)用程序在以下幾種情況下創(chuàng)建Context實(shí)例:

1) 創(chuàng)建Application 對(duì)象時(shí), 而且整個(gè)App共一個(gè)Application對(duì)象

2) 創(chuàng)建Service對(duì)象時(shí)

3) 創(chuàng)建Activity對(duì)象時(shí)

因此應(yīng)用程序App共有的Context數(shù)目公式為:

總Context實(shí)例個(gè)數(shù) = Service個(gè)數(shù) + Activity個(gè)數(shù) + 1(Application對(duì)應(yīng)的Context實(shí)例)

ActivityThread消息處理函數(shù)與本節(jié)相關(guān)的內(nèi)容如下:

public void handleMessage(Message msg) {             if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));             switch (msg.what) {                 case LAUNCH_ACTIVITY: { // 創(chuàng)建Activity對(duì)象                     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;                  case BIND_APPLICATION: // 創(chuàng)建Application對(duì)象                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");                     AppBindData data = (AppBindData)msg.obj;                     handleBindApplication(data);                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                     break;                          case CREATE_SERVICE: // 創(chuàng)建Service對(duì)象                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");                     handleCreateService((CreateServiceData)msg.obj);                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                     break;                                      case BIND_SERVICE:  // Bind Service對(duì)象                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");                     handleBindService((BindServiceData)msg.obj);                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                     break;             }         }

創(chuàng)建Application對(duì)象時(shí)創(chuàng)建Context實(shí)例

每個(gè)應(yīng)用程序在***次啟動(dòng)時(shí),都會(huì)首先創(chuàng)建一個(gè)Application對(duì)象。從startActivity流程可知,創(chuàng)建Application的時(shí)機(jī)在handleBindApplication()方法中,該函數(shù)位于 ActivityThread.java類中 ,相關(guān)代碼如下:

// ActivityThread.java    private void handleBindApplication(AppBindData data) {        try {             // If the app is being launched for full backup or restore, bring it up in             // a restricted environment with the base application class.             Application app = data.info.makeApplication(data.restrictedBackupMode, null);             mInitialApplication = app;             ...         } finally {             StrictMode.setThreadPolicy(savedPolicy);         }    }     // LoadedApk.java    public Application makeApplication(boolean forceDefaultAppClass,             Instrumentation instrumentation) {         if (mApplication != null) {             return mApplication;         }          Application app = null;          String appClass = mApplicationInfo.className;         if (forceDefaultAppClass || (appClass == null)) {             appClass = "android.app.Application";         }          try {             java.lang.ClassLoader cl = getClassLoader();             ContextImpl appContext = new ContextImpl(); // 創(chuàng)建ContextImpl實(shí)例             appContext.init(this, null, mActivityThread);             app = mActivityThread.mInstrumentation.newApplication(                     cl, appClass, appContext);             appContext.setOuterContext(app); // 將Application實(shí)例傳遞給Context實(shí)例         } catch (Exception e) {             ...         }         mActivityThread.mAllApplications.add(app);         mApplication = app;          return app;     }

創(chuàng)建Activity對(duì)象時(shí)創(chuàng)建Context實(shí)例

通過(guò)startActivity()或startActivityForResult()請(qǐng)求啟動(dòng)一個(gè)Activity時(shí),如果系統(tǒng)檢測(cè)需要新建一個(gè)Activity對(duì)象時(shí),就會(huì)回調(diào)handleLaunchActivity()方法,該方法繼而調(diào)用performLaunchActivity()方法,去創(chuàng)建一個(gè)Activity實(shí)例,并且回調(diào)onCreate(),onStart()方法等,函數(shù)都位于 ActivityThread.java類 ,相關(guān)代碼如下:

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {         ...         Activity a = performLaunchActivity(r, customIntent); // 到下一步          if (a != null) {             r.createdConfig = new Configuration(mConfiguration);             Bundle oldState = r.state;             handleResumeActivity(r.token, false, r.isForward,                     !r.activity.mFinished && !r.startsNotResumed);             ...         }         ...      }      private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {         ...             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) {             ...         }          try {             Application app = r.packageInfo.makeApplication(false, mInstrumentation);              if (activity != null) {                 Context appContext = createBaseContextForActivity(r, activity); // 創(chuàng)建Context                 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);                 }               mActivities.put(r.token, r);          } catch (SuperNotCalledException e) {             ...          } catch (Exception e) {             ...         }          return activity;     }
private Context createBaseContextForActivity(ActivityClientRecord r,             final Activity activity) {         ContextImpl appContext = new ContextImpl();  // 創(chuàng)建ContextImpl實(shí)例         appContext.init(r.packageInfo, r.token, this);         appContext.setOuterContext(activity);          // For debugging purposes, if the activity's package name contains the value of         // the "debug.use-second-display" system property as a substring, then show         // its content on a secondary display if there is one.         Context baseContext = appContext;         String pkgName = SystemProperties.get("debug.second-display.pkg");         if (pkgName != null && !pkgName.isEmpty()                 && r.packageInfo.mPackageName.contains(pkgName)) {             DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();             for (int displayId : dm.getDisplayIds()) {                 if (displayId != Display.DEFAULT_DISPLAY) {                     Display display = dm.getRealDisplay(displayId);                     baseContext = appContext.createDisplayContext(display);                     break;                 }             }         }         return baseContext;     }

創(chuàng)建Service對(duì)象時(shí)創(chuàng)建Context實(shí)例

通過(guò)startService或者bindService時(shí),如果系統(tǒng)檢測(cè)到需要新創(chuàng)建一個(gè)Service實(shí)例,就會(huì)回調(diào)handleCreateService()方法,完成相關(guān)數(shù)據(jù)操作。handleCreateService()函數(shù)位于 ActivityThread.java類,如下:

private void handleCreateService(CreateServiceData data) {         // If we are getting ready to gc after going to the background, well         // we are back active so skip it.         unscheduleGcIdler();          LoadedApk packageInfo = getPackageInfoNoCheck(                 data.info.applicationInfo, data.compatInfo);         Service service = null;         try {             java.lang.ClassLoader cl = packageInfo.getClassLoader();             service = (Service) cl.loadClass(data.info.name).newInstance();         } catch (Exception e) {             if (!mInstrumentation.onException(service, e)) {                 throw new RuntimeException(                     "Unable to instantiate service " + data.info.name                     + ": " + e.toString(), e);             }         }          try {             if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);              ContextImpl context = new ContextImpl(); // 創(chuàng)建ContextImpl實(shí)例             context.init(packageInfo, null, this);              Application app = packageInfo.makeApplication(false, mInstrumentation);             context.setOuterContext(service);             service.attach(context, this, data.info.name, data.token, app,                     ActivityManagerNative.getDefault());             service.onCreate();             mServices.put(data.token, service);             try {                 ActivityManagerNative.getDefault().serviceDoneExecuting(                         data.token, 0, 0, 0);             } catch (RemoteException e) {                 // nothing to do.             }         } catch (Exception e) {             if (!mInstrumentation.onException(service, e)) {                 throw new RuntimeException(                     "Unable to create service " + data.info.name                     + ": " + e.toString(), e);             }         }     }

上述就是小編為大家分享的Android中Context的作用是什么了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI