Context在Android应用开发中占据了绝对重要的地位,不管是Framework提供给我们的四大组件还是应用级别的Application,还是负责View展现层的View相关类,甚至连我们很多时候创建的实体类都会需要一个Context的引用,在Android Framework中,Context贯穿了整个Android MVC框架,它的应用很普遍。尽管如此,Context本质上还是一个普通的抽象类,我们在上面的装饰模式中提到Context类中的startActivity方法,实质上除了startActivity方法,Context还定义了大量相当牛的方法,这些方法不但与我们上面提到的四大组件密切相关,还与资源文件、文件管理、包管理、类加载、权限管理、系统服务获取等各式各样的功能相切合。
/**
* Interface to global information about an application environment. This is
* an abstract class whose implementation is provided by
* the Android system. It
* allows access to application-specific resources and classes, as well as
* up-calls for application-level operations such as launching activities,
* broadcasting and receiving intents, etc.
*/
public abstract class Context {
/**
* Same as {@link #startActivity(Intent, Bundle)} with no options
* specified.
*
* @param intent The description of the activity to start.
*
* @throws ActivityNotFoundException
*`
* @see #startActivity(Intent, Bundle)
* @see PackageManager#resolveActivity
*/
//启动一个Activity
public abstract void startActivity(@RequiresPermission Intent intent);
/**
* Same as {@link #startActivity(Intent, Bundle)} with no options
* specified.
*
* @param intent The description of the activity to start.
*
* @throws ActivityNotFoundException
*`
* @see #startActivity(Intent, Bundle)
* @see PackageManager#resolveActivity
*/
//启动一个Activity
public abstract void startActivity(@RequiresPermission Intent intent);
/**
* Same as {@link #startActivities(Intent[], Bundle)} with no options
* specified.
*
* @param intents An array of Intents to be started.
*
* @throws ActivityNotFoundException
*
* @see #startActivities(Intent[], Bundle)
* @see PackageManager#resolveActivity
*/
//启动多个Activity
public abstract void startActivities(@RequiresPermission Intent[] intents);
/**
* Launch multiple new activities. This is generally the same as calling
* {@link #startActivity(Intent)} for the first Intent in the array,
* that activity during its creation calling {@link #startActivity(Intent)}
* for the second entry, etc. Note that unlike that approach, generally
* none of the activities except the last in the array will be created
* at this point, but rather will be created when the user first visits
* them (due to pressing back from the activity on top).
*
* <p>This method throws {@link ActivityNotFoundException}
* if there was no Activity found for <em>any</em> given Intent. In this
* case the state of the activity stack is undefined (some Intents in the
* list may be on it, some not), so you probably want to avoid such situations.
*
* @param intents An array of Intents to be started.
* @param options Additional options for how the Activity should be started.
* See {@link android.content.Context#startActivity(Intent, Bundle)}
* Context.startActivity(Intent, Bundle)} for more details.
*
* @throws ActivityNotFoundException
*
* @see #startActivities(Intent[])
* @see PackageManager#resolveActivity
*/
//启动多个Activity
public abstract void startActivities(@RequiresPermission Intent[] intents, Bundle options);
/** Return the full application info for this context's package. */
//获取应用程序信息
public abstract ApplicationInfo getApplicationInfo();
/**
* Request that a given application service be started. The Intent
* should either contain the complete class name of a specific service
* implementation to start, or a specific package name to target. If the
* Intent is less specified, it logs a warning about this. In this case any of the
* multiple matching services may be used. If this service
* is not already running, it will be instantiated and started (creating a
* process for it if needed); if it is running then it remains running.
*
* <p>Every call to this method will result in a corresponding call to
* the target service's {@link android.app.Service#onStartCommand} method,
* with the <var>intent</var> given here. This provides a convenient way
* to submit jobs to a service without having to bind and call on to its
* interface.
*
* <p>Using startService() overrides the default service lifetime that is
* managed by {@link #bindService}: it requires the service to remain
* running until {@link #stopService} is called, regardless of whether
* any clients are connected to it. Note that calls to startService()
* do not nest: no matter how many times you call startService(),
* a single call to {@link #stopService} will stop it.
*
* <p>The system attempts to keep running services around as much as
* possible. The only time they should be stopped is if the current
* foreground application is using so many resources that the service needs
* to be killed. If any errors happen in the service's process, it will
* automatically be restarted.
*
* <p>This function will throw {@link SecurityException} if you do not
* have permission to start the given service.
*
* <p class="note"><strong>Note:</strong> Each call to startService()
* results in significant work done by the system to manage service
* lifecycle surrounding the processing of the intent, which can take
* multiple milliseconds of CPU time. Due to this cost, startService()
* should not be used for frequent intent delivery to a service, and only
* for scheduling significant work. Use {@link #bindService bound services}
* for high frequency calls.
* </p>
*
* @param service Identifies the service to be started. The Intent must be
* fully explicit (supplying a component name). Additional values
* may be included in the Intent extras to supply arguments along with
* this specific start call.
*
* @return If the service is being started or is already running, the
* {@link ComponentName} of the actual service that was started is
* returned; else if the service does not exist null is returned.
*
* @throws SecurityException If the caller does not have permission to access the service
* or the service can not be found.
* @throws IllegalStateException If the application is in a state where the service
* can not be started (such as not in the foreground in a state when services are allowed).
*
* @see #stopService
* @see #bindService
*/
//启动一个Service
@Nullable
public abstract ComponentName startService(Intent service);
/**
* Request that a given application service be stopped. If the service is
* not running, nothing happens. Otherwise it is stopped. Note that calls
* to startService() are not counted -- this stops the service no matter
* how many times it was started.
*
* <p>Note that if a stopped service still has {@link ServiceConnection}
* objects bound to it with the {@link #BIND_AUTO_CREATE} set, it will
* not be destroyed until all of these bindings are removed. See
* the {@link android.app.Service} documentation for more details on a
* service's lifecycle.
*
* <p>This function will throw {@link SecurityException} if you do not
* have permission to stop the given service.
*
* @param service Description of the service to be stopped. The Intent must be either
* fully explicit (supplying a component name) or specify a specific package
* name it is targetted to.
*
* @return If there is a service matching the given Intent that is already
* running, then it is stopped and {@code true} is returned; else {@code false} is returned.
*
* @throws SecurityException If the caller does not have permission to access the service
* or the service can not be found.
* @throws IllegalStateException If the application is in a state where the service
* can not be started (such as not in the foreground in a state when services are allowed).
*
* @see #startService
*/
//停止一个Service
public abstract boolean stopService(Intent service);
/**
* Connect to an application service, creating it if needed. This defines
* a dependency between your application and the service. The given
* <var>conn</var> will receive the service object when it is created and be
* told if it dies and restarts. The service will be considered required
* by the system only for as long as the calling context exists. For
* example, if this Context is an Activity that is stopped, the service will
* not be required to continue running until the Activity is resumed.
*
* <p>This function will throw {@link SecurityException} if you do not
* have permission to bind to the given service.
*
* <p class="note">Note: this method <em>can not be called from a
* {@link BroadcastReceiver} component</em>. A pattern you can use to
* communicate from a BroadcastReceiver to a Service is to call
* {@link #startService} with the arguments containing the command to be
* sent, with the service calling its
* {@link android.app.Service#stopSelf(int)} method when done executing
* that command. See the API demo App/Service/Service Start Arguments
* Controller for an illustration of this. It is okay, however, to use
* this method from a BroadcastReceiver that has been registered with
* {@link #registerReceiver}, since the lifetime of this BroadcastReceiver
* is tied to another object (the one that registered it).</p>
*
* @param service Identifies the service to connect to. The Intent must
* specify an explicit component name.
* @param conn Receives information as the service is started and stopped.
* This must be a valid ServiceConnection object; it must not be null.
* @param flags Operation options for the binding. May be 0,
* {@link #BIND_AUTO_CREATE}, {@link #BIND_DEBUG_UNBIND},
* {@link #BIND_NOT_FOREGROUND}, {@link #BIND_ABOVE_CLIENT},
* {@link #BIND_ALLOW_OOM_MANAGEMENT}, or
* {@link #BIND_WAIVE_PRIORITY}.
* @return If you have successfully bound to the service, {@code true} is returned;
* {@code false} is returned if the connection is not made so you will not
* receive the service object. However, you should still call
* {@link #unbindService} to release the connection.
*
* @throws SecurityException If the caller does not have permission to access the service
* or the service can not be found.
*
* @see #unbindService
* @see #startService
* @see #BIND_AUTO_CREATE
* @see #BIND_DEBUG_UNBIND
* @see #BIND_NOT_FOREGROUND
*/
//绑定一个Service到Activity
public abstract boolean bindService(@RequiresPermission Intent service,
@NonNull ServiceConnection conn, @BindServiceFlags int flags);
/**
* Disconnect from an application service. You will no longer receive
* calls as the service is restarted, and the service is now allowed to
* stop at any time.
*
* @param conn The connection interface previously supplied to
* bindService(). This parameter must not be null.
*
* @see #bindService
*/
//解绑一个Service到Activity
public abstract void unbindService(@NonNull ServiceConnection conn);
/**
* Broadcast the given intent to all interested BroadcastReceivers. This
* call is asynchronous; it returns immediately, and you will continue
* executing while the receivers are run. No results are propagated from
* receivers and receivers can not abort the broadcast. If you want
* to allow receivers to propagate results or abort the broadcast, you must
* send an ordered broadcast using
* {@link #sendOrderedBroadcast(Intent, String)}.
*
* <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
*
* @param intent The Intent to broadcast; all receivers matching this
* Intent will receive the broadcast.
*
* @see android.content.BroadcastReceiver
* @see #registerReceiver
* @see #sendBroadcast(Intent, String)
* @see #sendOrderedBroadcast(Intent, String)
* @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
*/
//发送一个广播
public abstract void sendBroadcast(@RequiresPermission Intent intent);
/**
* Broadcast the given intent to all interested BroadcastReceivers, allowing
* an optional required permission to be enforced. This
* call is asynchronous; it returns immediately, and you will continue
* executing while the receivers are run. No results are propagated from
* receivers and receivers can not abort the broadcast. If you want
* to allow receivers to propagate results or abort the broadcast, you must
* send an ordered broadcast using
* {@link #sendOrderedBroadcast(Intent, String)}.
*
* <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
*
* @param intent The Intent to broadcast; all receivers matching this
* Intent will receive the broadcast.
* @param receiverPermission (optional) String naming a permission that
* a receiver must hold in order to receive your broadcast.
* If null, no permission is required.
*
* @see android.content.BroadcastReceiver
* @see #registerReceiver
* @see #sendBroadcast(Intent)
* @see #sendOrderedBroadcast(Intent, String)
* @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
*/
//发送一个广播
public abstract void sendBroadcast(@RequiresPermission Intent intent,
@Nullable String receiverPermission);
/**
* Like {@link #sendBroadcast(Intent, String)}, but also allows specification
* of an associated app op as per {@link android.app.AppOpsManager}.
* @hide
*/
public abstract void sendBroadcast(Intent intent,
String receiverPermission, int appOp);
/**
* Broadcast the given intent to all interested BroadcastReceivers, delivering
* them one at a time to allow more preferred receivers to consume the
* broadcast before it is delivered to less preferred receivers. This
* call is asynchronous; it returns immediately, and you will continue
* executing while the receivers are run.
*
* <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
*
* @param intent The Intent to broadcast; all receivers matching this
* Intent will receive the broadcast.
* @param receiverPermission (optional) String naming a permissions that
* a receiver must hold in order to receive your broadcast.
* If null, no permission is required.
*
* @see android.content.BroadcastReceiver
* @see #registerReceiver
* @see #sendBroadcast(Intent)
* @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
*/
//发送一个有序广播
public abstract void sendOrderedBroadcast(@RequiresPermission Intent intent,
@Nullable String receiverPermission);
/**
* Version of {@link #sendBroadcast(Intent)} that allows you to
* receive data back from the broadcast. This is accomplished by
* supplying your own BroadcastReceiver when calling, which will be
* treated as a final receiver at the end of the broadcast -- its
* {@link BroadcastReceiver#onReceive} method will be called with
* the result values collected from the other receivers. The broadcast will
* be serialized in the same way as calling
* {@link #sendOrderedBroadcast(Intent, String)}.
*
* <p>Like {@link #sendBroadcast(Intent)}, this method is
* asynchronous; it will return before
* resultReceiver.onReceive() is called.
*
* <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
*
* @param intent The Intent to broadcast; all receivers matching this
* Intent will receive the broadcast.
* @param receiverPermission String naming a permissions that
* a receiver must hold in order to receive your broadcast.
* If null, no permission is required.
* @param resultReceiver Your own BroadcastReceiver to treat as the final
* receiver of the broadcast.
* @param scheduler A custom Handler with which to schedule the
* resultReceiver callback; if null it will be
* scheduled in the Context's main thread.
* @param initialCode An initial value for the result code. Often
* Activity.RESULT_OK.
* @param initialData An initial value for the result data. Often
* null.
* @param initialExtras An initial value for the result extras. Often
* null.
*
* @see #sendBroadcast(Intent)
* @see #sendBroadcast(Intent, String)
* @see #sendOrderedBroadcast(Intent, String)
* @see android.content.BroadcastReceiver
* @see #registerReceiver
* @see android.app.Activity#RESULT_OK
*/
//发送一个有序广播
public abstract void sendOrderedBroadcast(@RequiresPermission @NonNull Intent intent,
@Nullable String receiverPermission, @Nullable BroadcastReceiver resultReceiver,
@Nullable Handler scheduler, int initialCode, @Nullable String initialData,
@Nullable Bundle initialExtras);
/**
* <p>Perform a {@link #sendBroadcast(Intent)} that is "sticky," meaning the
* Intent you are sending stays around after the broadcast is complete,
* so that others can quickly retrieve that data through the return
* value of {@link #registerReceiver(BroadcastReceiver, IntentFilter)}. In
* all other ways, this behaves the same as
* {@link #sendBroadcast(Intent)}.
*
* @deprecated Sticky broadcasts should not be used. They provide no security (anyone
* can access them), no protection (anyone can modify them), and many other problems.
* The recommended pattern is to use a non-sticky broadcast to report that <em>something</em>
* has changed, with another mechanism for apps to retrieve the current value whenever
* desired.
*
* @param intent The Intent to broadcast; all receivers matching this
* Intent will receive the broadcast, and the Intent will be held to
* be re-broadcast to future receivers.
*
* @see #sendBroadcast(Intent)
* @see #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle)
*/
//发送一个会滞留的广播
@Deprecated
@RequiresPermission(android.Manifest.permission.BROADCAST_STICKY)
public abstract void sendStickyBroadcast(@RequiresPermission Intent intent);
/**
* <p>Version of {@link #sendStickyBroadcast} that allows you to
* receive data back from the broadcast. This is accomplished by
* supplying your own BroadcastReceiver when calling, which will be
* treated as a final receiver at the end of the broadcast -- its
* {@link BroadcastReceiver#onReceive} method will be called with
* the result values collected from the other receivers. The broadcast will
* be serialized in the same way as calling
* {@link #sendOrderedBroadcast(Intent, String)}.
*
* <p>Like {@link #sendBroadcast(Intent)}, this method is
* asynchronous; it will return before
* resultReceiver.onReceive() is called. Note that the sticky data
* stored is only the data you initially supply to the broadcast, not
* the result of any changes made by the receivers.
*
* <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
*
* @deprecated Sticky broadcasts should not be used. They provide no security (anyone
* can access them), no protection (anyone can modify them), and many other problems.
* The recommended pattern is to use a non-sticky broadcast to report that <em>something</em>
* has changed, with another mechanism for apps to retrieve the current value whenever
* desired.
*
* @param intent The Intent to broadcast; all receivers matching this
* Intent will receive the broadcast.
* @param resultReceiver Your own BroadcastReceiver to treat as the final
* receiver of the broadcast.
* @param scheduler A custom Handler with which to schedule the
* resultReceiver callback; if null it will be
* scheduled in the Context's main thread.
* @param initialCode An initial value for the result code. Often
* Activity.RESULT_OK.
* @param initialData An initial value for the result data. Often
* null.
* @param initialExtras An initial value for the result extras. Often
* null.
*
* @see #sendBroadcast(Intent)
* @see #sendBroadcast(Intent, String)
* @see #sendOrderedBroadcast(Intent, String)
* @see #sendStickyBroadcast(Intent)
* @see android.content.BroadcastReceiver
* @see #registerReceiver
* @see android.app.Activity#RESULT_OK
*/
//发送一个会滞留的广播
@Deprecated
@RequiresPermission(android.Manifest.permission.BROADCAST_STICKY)
public abstract void sendStickyOrderedBroadcast(@RequiresPermission Intent intent,
BroadcastReceiver resultReceiver,
@Nullable Handler scheduler, int initialCode, @Nullable String initialData,
@Nullable Bundle initialExtras);
/**
* Register a BroadcastReceiver to be run in the main activity thread. The
* <var>receiver</var> will be called with any broadcast Intent that
* matches <var>filter</var>, in the main application thread.
*
* <p>The system may broadcast Intents that are "sticky" -- these stay
* around after the broadcast has finished, to be sent to any later
* registrations. If your IntentFilter matches one of these sticky
* Intents, that Intent will be returned by this function
* <strong>and</strong> sent to your <var>receiver</var> as if it had just
* been broadcast.
*
* <p>There may be multiple sticky Intents that match <var>filter</var>,
* in which case each of these will be sent to <var>receiver</var>. In
* this case, only one of these can be returned directly by the function;
* which of these that is returned is arbitrarily decided by the system.
*
* <p>If you know the Intent your are registering for is sticky, you can
* supply null for your <var>receiver</var>. In this case, no receiver is
* registered -- the function simply returns the sticky Intent that
* matches <var>filter</var>. In the case of multiple matches, the same
* rules as described above apply.
*
* <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
*
* <p>As of {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH}, receivers
* registered with this method will correctly respect the
* {@link Intent#setPackage(String)} specified for an Intent being broadcast.
* Prior to that, it would be ignored and delivered to all matching registered
* receivers. Be careful if using this for security.</p>
*
* <p class="note">Note: this method <em>cannot be called from a
* {@link BroadcastReceiver} component;</em> that is, from a BroadcastReceiver
* that is declared in an application's manifest. It is okay, however, to call
* this method from another BroadcastReceiver that has itself been registered
* at run time with {@link #registerReceiver}, since the lifetime of such a
* registered BroadcastReceiver is tied to the object that registered it.</p>
*
* @param receiver The BroadcastReceiver to handle the broadcast.
* @param filter Selects the Intent broadcasts to be received.
*
* @return The first sticky intent found that matches <var>filter</var>,
* or null if there are none.
*
* @see #registerReceiver(BroadcastReceiver, IntentFilter, String, Handler)
* @see #sendBroadcast
* @see #unregisterReceiver
*/
//注册一个广播接收者
@Nullable
public abstract Intent registerReceiver(@Nullable BroadcastReceiver receiver,
IntentFilter filter);
/**
* Register to receive intent broadcasts, to run in the context of
* <var>scheduler</var>. See
* {@link #registerReceiver(BroadcastReceiver, IntentFilter)} for more
* information. This allows you to enforce permissions on who can
* broadcast intents to your receiver, or have the receiver run in
* a different thread than the main application thread.
*
* <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
*
* <p>As of {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH}, receivers
* registered with this method will correctly respect the
* {@link Intent#setPackage(String)} specified for an Intent being broadcast.
* Prior to that, it would be ignored and delivered to all matching registered
* receivers. Be careful if using this for security.</p>
*
* @param receiver The BroadcastReceiver to handle the broadcast.
* @param filter Selects the Intent broadcasts to be received.
* @param broadcastPermission String naming a permissions that a
* broadcaster must hold in order to send an Intent to you. If null,
* no permission is required.
* @param scheduler Handler identifying the thread that will receive
* the Intent. If null, the main thread of the process will be used.
*
* @return The first sticky intent found that matches <var>filter</var>,
* or null if there are none.
*
* @see #registerReceiver(BroadcastReceiver, IntentFilter)
* @see #sendBroadcast
* @see #unregisterReceiver
*/
//注册一个广播接收者
@Nullable
public abstract Intent registerReceiver(BroadcastReceiver receiver,
IntentFilter filter, @Nullable String broadcastPermission,
@Nullable Handler scheduler);
/**
* Unregister a previously registered BroadcastReceiver. <em>All</em>
* filters that have been registered for this BroadcastReceiver will be
* removed.
*
* @param receiver The BroadcastReceiver to unregister.
*
* @see #registerReceiver
*/
//取消注册一个广播接收者
public abstract void unregisterReceiver(BroadcastReceiver receiver);
/** Return a ContentResolver instance for your application's package. */
//获取一个ContentResolver对象
public abstract ContentResolver getContentResolver();
/**
* Return the Looper for the main thread of the current process. This is
* the thread used to dispatch calls to application components (activities,
* services, etc).
* <p>
* By definition, this method returns the same result as would be obtained
* by calling {@link Looper#getMainLooper() Looper.getMainLooper()}.
* </p>
*
* @return The main looper.
*/
// 获取主线程中的looper
public abstract Looper getMainLooper();
/**
* Return the context of the single, global Application object of the
* current process. This generally should only be used if you need a
* Context whose lifecycle is separate from the current context, that is
* tied to the lifetime of the process rather than the current component.
*
* <p>Consider for example how this interacts with
* {@link #registerReceiver(BroadcastReceiver, IntentFilter)}:
* <ul>
* <li> <p>If used from an Activity context, the receiver is being registered
* within that activity. This means that you are expected to unregister
* before the activity is done being destroyed; in fact if you do not do
* so, the framework will clean up your leaked registration as it removes
* the activity and log an error. Thus, if you use the Activity context
* to register a receiver that is static (global to the process, not
* associated with an Activity instance) then that registration will be
* removed on you at whatever point the activity you used is destroyed.
* <li> <p>If used from the Context returned here, the receiver is being
* registered with the global state associated with your application. Thus
* it will never be unregistered for you. This is necessary if the receiver
* is associated with static data, not a particular component. However
* using the ApplicationContext elsewhere can easily lead to serious leaks
* if you forget to unregister, unbind, etc.
* </ul>
*/
// 获取应用级别的Context对象
public abstract Context getApplicationContext();
/**
* Return the handle to a system-level service by name. The class of the
* returned object varies by the requested name. Currently available names
* are:
*
* <dl>
* <dt> {@link #WINDOW_SERVICE} ("window")
* <dd> The top-level window manager in which you can place custom
* windows. The returned object is a {@link android.view.WindowManager}.
* <dt> {@link #LAYOUT_INFLATER_SERVICE} ("layout_inflater")
* <dd> A {@link android.view.LayoutInflater} for inflating layout resources
* in this context.
* <dt> {@link #ACTIVITY_SERVICE} ("activity")
* <dd> A {@link android.app.ActivityManager} for interacting with the
* global activity state of the system.
* <dt> {@link #POWER_SERVICE} ("power")
* <dd> A {@link android.os.PowerManager} for controlling power
* management.
* <dt> {@link #ALARM_SERVICE} ("alarm")
* <dd> A {@link android.app.AlarmManager} for receiving intents at the
* time of your choosing.
* <dt> {@link #NOTIFICATION_SERVICE} ("notification")
* <dd> A {@link android.app.NotificationManager} for informing the user
* of background events.
* <dt> {@link #KEYGUARD_SERVICE} ("keyguard")
* <dd> A {@link android.app.KeyguardManager} for controlling keyguard.
* <dt> {@link #LOCATION_SERVICE} ("location")
* <dd> A {@link android.location.LocationManager} for controlling location
* (e.g., GPS) updates.
* <dt> {@link #SEARCH_SERVICE} ("search")
* <dd> A {@link android.app.SearchManager} for handling search.
* <dt> {@link #VIBRATOR_SERVICE} ("vibrator")
* <dd> A {@link android.os.Vibrator} for interacting with the vibrator
* hardware.
* <dt> {@link #CONNECTIVITY_SERVICE} ("connection")
* <dd> A {@link android.net.ConnectivityManager ConnectivityManager} for
* handling management of network connections.
* <dt> {@link #WIFI_SERVICE} ("wifi")
* <dd> A {@link android.net.wifi.WifiManager WifiManager} for management of Wi-Fi
* connectivity. On releases before NYC, it should only be obtained from an application
* context, and not from any other derived context to avoid memory leaks within the calling
* process.
* <dt> {@link #WIFI_AWARE_SERVICE} ("wifiaware")
* <dd> A {@link android.net.wifi.aware.WifiAwareManager WifiAwareManager} for management of
* Wi-Fi Aware discovery and connectivity.
* <dt> {@link #WIFI_P2P_SERVICE} ("wifip2p")
* <dd> A {@link android.net.wifi.p2p.WifiP2pManager WifiP2pManager} for management of
* Wi-Fi Direct connectivity.
* <dt> {@link #INPUT_METHOD_SERVICE} ("input_method")
* <dd> An {@link android.view.inputmethod.InputMethodManager InputMethodManager}
* for management of input methods.
* <dt> {@link #UI_MODE_SERVICE} ("uimode")
* <dd> An {@link android.app.UiModeManager} for controlling UI modes.
* <dt> {@link #DOWNLOAD_SERVICE} ("download")
* <dd> A {@link android.app.DownloadManager} for requesting HTTP downloads
* <dt> {@link #BATTERY_SERVICE} ("batterymanager")
* <dd> A {@link android.os.BatteryManager} for managing battery state
* <dt> {@link #JOB_SCHEDULER_SERVICE} ("taskmanager")
* <dd> A {@link android.app.job.JobScheduler} for managing scheduled tasks
* <dt> {@link #NETWORK_STATS_SERVICE} ("netstats")
* <dd> A {@link android.app.usage.NetworkStatsManager NetworkStatsManager} for querying network
* usage statistics.
* <dt> {@link #HARDWARE_PROPERTIES_SERVICE} ("hardware_properties")
* <dd> A {@link android.os.HardwarePropertiesManager} for accessing hardware properties.
* </dl>
*
* <p>Note: System services obtained via this API may be closely associated with
* the Context in which they are obtained from. In general, do not share the
* service objects between various different contexts (Activities, Applications,
* Services, Providers, etc.)
*
* @param name The name of the desired service.
*
* @return The service or null if the name does not exist.
*
* @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 #TELEPHONY_SUBSCRIPTION_SERVICE
* @see android.telephony.SubscriptionManager
* @see #CARRIER_CONFIG_SERVICE
* @see android.telephony.CarrierConfigManager
* @see #INPUT_METHOD_SERVICE
* @see android.view.inputmethod.InputMethodManager
* @see #UI_MODE_SERVICE
* @see android.app.UiModeManager
* @see #DOWNLOAD_SERVICE
* @see android.app.DownloadManager
* @see #BATTERY_SERVICE
* @see android.os.BatteryManager
* @see #JOB_SCHEDULER_SERVICE
* @see android.app.job.JobScheduler
* @see #NETWORK_STATS_SERVICE
* @see android.app.usage.NetworkStatsManager
* @see android.os.HardwarePropertiesManager
* @see #HARDWARE_PROPERTIES_SERVICE
*/
//获取应用的系统服务
public abstract @Nullable Object getSystemService(@ServiceName @NonNull String name);
/**
* Returns a Resources instance for the application's package.
* <p>
* <strong>Note:</strong> Implementations of this method should return
* a Resources instance that is consistent with the AssetManager instance
* returned by {@link #getAssets()}. For example, they should share the
* same {@link Configuration} object.
*
* @return a Resources instance for the application's package
* @see #getAssets()
*/
//获取Resource对象处理资源文件
public abstract Resources getResources();
/**
* Retrieve and hold the contents of the preferences file 'name', returning
* a SharedPreferences through which you can retrieve and modify its
* values. Only one instance of the SharedPreferences object is returned
* to any callers for the same name, meaning they will see each other's
* edits as soon as they are made.
*
* @param name Desired preferences file. If a preferences file by this name
* does not exist, it will be created when you retrieve an
* editor (SharedPreferences.edit()) and then commit changes (Editor.commit()).
* @param mode Operating mode.
*
* @return The single {@link SharedPreferences} instance that can be used
* to retrieve and modify the preference values.
*
* @see #MODE_PRIVATE
*/
//获取SharedPreferences对象
public abstract SharedPreferences getSharedPreferences(String name, @PreferencesMode int mode);
/**
* Returns the absolute path to the directory on the primary shared/external
* storage device where the application can place persistent files it owns.
* These files are internal to the applications, and not typically visible
* to the user as media.
* <p>
* This is like {@link #getFilesDir()} in that these files will be deleted
* when the application is uninstalled, however there are some important
* differences:
* <ul>
* <li>Shared storage may not always be available, since removable media can
* be ejected by the user. Media state can be checked using
* {@link Environment#getExternalStorageState(File)}.
* <li>There is no security enforced with these files. For example, any
* application holding
* {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
* these files.
* </ul>
* <p>
* If a shared storage device is emulated (as determined by
* {@link Environment#isExternalStorageEmulated(File)}), it's contents are
* backed by a private user data partition, which means there is little
* benefit to storing data here instead of the private directories returned
* by {@link #getFilesDir()}, etc.
* <p>
* Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
* are required to read or write to the returned path; it's always
* accessible to the calling app. This only applies to paths generated for
* package name of the calling application. To access paths belonging to
* other packages,
* {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} and/or
* {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
* <p>
* On devices with multiple users (as described by {@link UserManager}),
* each user has their own isolated shared storage. Applications only have
* access to the shared storage for the user they're running as.
* <p>
* The returned path may change over time if different shared storage media
* is inserted, so only relative paths should be persisted.
* <p>
* Here is an example of typical code to manipulate a file in an
* application's shared storage:
* </p>
* {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
* private_file}
* <p>
* If you supply a non-null <var>type</var> to this function, the returned
* file will be a path to a sub-directory of the given type. Though these
* files are not automatically scanned by the media scanner, you can
* explicitly add them to the media database with
* {@link android.media.MediaScannerConnection#scanFile(Context, String[], String[], android.media.MediaScannerConnection.OnScanCompletedListener)
* MediaScannerConnection.scanFile}. Note that this is not the same as
* {@link android.os.Environment#getExternalStoragePublicDirectory
* Environment.getExternalStoragePublicDirectory()}, which provides
* directories of media shared by all applications. The directories returned
* here are owned by the application, and their contents will be removed
* when the application is uninstalled. Unlike
* {@link android.os.Environment#getExternalStoragePublicDirectory
* Environment.getExternalStoragePublicDirectory()}, the directory returned
* here will be automatically created for you.
* <p>
* Here is an example of typical code to manipulate a picture in an
* application's shared storage and add it to the media database:
* </p>
* {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
* private_picture}
*
* @param type The type of files directory to return. May be {@code null}
* for the root of the files directory or one of the following
* 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}.
* @return the absolute path to application-specific directory. May return
* {@code null} if shared storage is not currently available.
* @see #getFilesDir
* @see #getExternalFilesDirs(String)
* @see Environment#getExternalStorageState(File)
* @see Environment#isExternalStorageEmulated(File)
* @see Environment#isExternalStorageRemovable(File)
*/
//获取外部文件存储目录
@Nullable
public abstract File getExternalFilesDir(@Nullable String type);
/**
* Returns absolute paths to application-specific directories on all
* shared/external storage devices where the application can place
* persistent files it owns. These files are internal to the application,
* and not typically visible to the user as media.
* <p>
* This is like {@link #getFilesDir()} in that these files will be deleted
* when the application is uninstalled, however there are some important
* differences:
* <ul>
* <li>Shared storage may not always be available, since removable media can
* be ejected by the user. Media state can be checked using
* {@link Environment#getExternalStorageState(File)}.
* <li>There is no security enforced with these files. For example, any
* application holding
* {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
* these files.
* </ul>
* <p>
* If a shared storage device is emulated (as determined by
* {@link Environment#isExternalStorageEmulated(File)}), it's contents are
* backed by a private user data partition, which means there is little
* benefit to storing data here instead of the private directories returned
* by {@link #getFilesDir()}, etc.
* <p>
* Shared storage devices returned here are considered a stable part of the
* device, including physical media slots under a protective cover. The
* returned paths do not include transient devices, such as USB flash drives
* connected to handheld devices.
* <p>
* An application may store data on any or all of the returned devices. For
* example, an app may choose to store large files on the device with the
* most available space, as measured by {@link StatFs}.
* <p>
* No additional permissions are required for the calling app to read or
* write files under the returned path. Write access outside of these paths
* on secondary external storage devices is not available.
* <p>
* The returned path may change over time if different shared storage media
* is inserted, so only relative paths should be persisted.
*
* @param type The type of files directory to return. May be {@code null}
* for the root of the files directory or one of the following
* 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}.
* @return the absolute paths to application-specific directories. Some
* individual paths may be {@code null} if that shared storage is
* not currently available. The first path returned is the same as
* {@link #getExternalFilesDir(String)}.
* @see #getExternalFilesDir(String)
* @see Environment#getExternalStorageState(File)
* @see Environment#isExternalStorageEmulated(File)
* @see Environment#isExternalStorageRemovable(File)
*/
//获取多个(如果有的话)外部文件存储目录
public abstract File[] getExternalFilesDirs(String type);
}
以上这些方法我们在开发中经常用到,当然这里仅仅是定义一个声明,如上面装饰模式源码分析所说,Context中方法的所有实现均由ContextImpl类承担,具体相关方法的实现这里就不再多说了。
Android应用开发中我们从来都是从一个Activity的onCreate方法开始的,从未接触过类似main一样的程序入口方法,但是main方法确实存在,在ActivityThread类中。
/**
* This manages the execution of the main thread in an
* application process, scheduling and executing activities,
* broadcasts, and other operations on it as the activity
* manager requests.
*
* {@hide}
*/
public final class ActivityThread {
}
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
// 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检测,稍后会打开
CloseGuard.setEnabled(false);
//当前用户初始化环境参数
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
//配置EventLogger
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("<pre-initialized>");
//准备循环主线程(也就是当前线程)中的Looper
Looper.prepareMainLooper();
//构造ActivityThread对象并attach
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);
/// M: ANR Debug Mechanism
mAnrAppManager.setMessageLogger(Looper.myLooper());
//调用Looper的loop方法使主线程中消息循环
Looper.loop();
//如果代码执行到这里说明主线程消息循环出现异常,这时则抛出异常终止系统运行
throw new RuntimeException("Main thread loop unexpectedly exited");
}
ActivityThread中的main方法逻辑并不多,大多复杂的逻辑被封装到了ActivityThread类中,而这里我们也主要只关注ActivityThread类,在上面的main方法中构造了一个ActivityThread对象,随后又为sMainThreadHandler这个handler引用赋值,sMainThreadHandler为ActivityThread的类变量,这里sMainThreadHandler指向的对象是由ActivityThread的getHandler方法获取,该方法只是单纯返回一个H类型的对象。
#ActivityThread
final H mH = new H();
final Handler getHandler() {
return mH;
}
H是ActivityThread的一个私有内部类,继承于Handler,其作用很简单,处理消息以及将消息压入队列,,在H的handleMessage方法中可以得到一段处理Activity启动的逻辑。
#ActivityThread
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");
//获取记录Activity状态等相关信息的ActivityClientRecord对象
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
//获取PackageInfo
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
//启动Activity
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
... ...
}
}
在处理启动Activity的这段分支代码中,主要是调用了handleLaunchActivity方法来处理启动的具体逻辑,在handleLaunchActivity方法中又会调用performLaunchActivity方法来获取一个Activity实例。
#ActivityThread
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
... ...
Activity a = performLaunchActivity(r, customIntent);
... ...
}
而这个performLanchActivity方法才是正真处理Activity启动的关键所在,其中对大量Activity相关参数进行初始化。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
//获取ActivityInfo信息
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
//获取要启动的Activity的组件信息
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);
}
//获取Context对象
ContextImpl appContext = createBaseContextForActivity(r);
//这里开始构造具体的Activity对象
Activity activity = null;
try {
//获取PackageInfo所描述的类加载器
java.lang.ClassLoader cl = appContext.getClassLoader();
//通过Instrumentation对象获取一个Activity对象
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
//设置相关参数准备初始化Activity
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
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对象
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) {
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
//构造Configuration 对象
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
appContext.setOuterContext(activity);
//通过attach方法将上述信息保存到activity内部
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
//设置主题
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
//根据是否需要持久化调用callActivityOnCreate方法通知Activity已被创建和启动
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
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.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
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所需要的Context对象构造过程:
#ActivityThread
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
final int displayId;
try {
displayId = ActivityManager.getService().getActivityDisplayId(r.token);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
ContextImpl appContext = ContextImpl.createActivityContext(
this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
// 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.
String pkgName = SystemProperties.get("debug.second-display.pkg");
if (pkgName != null && !pkgName.isEmpty()
&& r.packageInfo.mPackageName.contains(pkgName)) {
for (int id : dm.getDisplayIds()) {
if (id != Display.DEFAULT_DISPLAY) {
Display display =
dm.getCompatibleDisplay(id, appContext.getResources());
appContext = (ContextImpl) appContext.createDisplayContext(display);
break;
}
}
}
return appContext;
}
在createBaseContextForActivity中 , 通过ContextImpl的静态方法createActivityContext获得一个ContextImpl的实例对象。并通过 appContext.setOuterContext(activity);方法将两者进行关联。
Applicaition创建过程:
#ActivityThread.H.handleMesage方法
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
#ActivityThread
private void handleBindApplication(AppBindData data) {
.......
Application app;
final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy();
try {
// If the app is being launched for full backup or restore, bring it up in
// a restricted environment with the base application class.
app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
......
}
handleBindApplication中调用makeApplication方法生成一个Application对象。
#LoadedApk
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
//相对成员变量mApplication做非空判断避免重复构造
if (mApplication != null) {
return mApplication;
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"initializeJavaContextClassLoader");
initializeJavaContextClassLoader();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
//获取一个ContextImpl对象
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
//获取一个Application对象
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
//将Application与得到的ContextImpl进行关联
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!instrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
}
// Rewrite the R 'constants' for all library apks.
SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers();
final int N = packageIdentifiers.size();
for (int i = 0; i < N; i++) {
final int id = packageIdentifiers.keyAt(i);
if (id == 0x01 || id == 0x7f) {
continue;
}
rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
return app;
}
这里可以看到,虽然具体代码不尽相同,但是创建Applcation和Context以及将两者关联的套路基本是与Activity一致,当然还有Service,具体不说了。
参考《Android源码设计模式》