Android之Context的源码分析
1.Context是什么
从Context的字面意思是环境,上下文,在Android开发中,Context就是Android系统中每一个App的环境和上下文。对于刚入坑Android的小伙伴来说Context是一个神奇而又无所不能的东西。开发过程中会经常用到Context,比如最基础的启动一个Activity啦,发送一个广播啦,获取应用基本信息啦。今天我们就从源码里探究一下,Context到底还有哪些隐藏技能。
从源码层面理解,Context是一个抽象类,它里面定义了很多抽象方法,而Context的具体实现类是ContextWrapper和ContextImpl,通过简单的查看ContextWrapper和ContextImpl源码,发现这两货都是Context的代理类,Context中的抽象方法的真正实现在其子类里。
他们之间的继承关系如下:
看完继承关系,我们来看下Context的源码。在源码中我标注了Context中重要的抽象方法的功能。
public abstract class Context {
// 资源相关
public abstract AssetManager getAssets();
public abstract Resources getResources();
// 包名管理
public abstract PackageManager getPackageManager();
// 获取内容提供者ContentResolver
public abstract ContentResolver getContentResolver();
// 获取app全局的Context实例
public abstract Context getApplicationContext();
// 反射相关
public abstract ClassLoader getClassLoader();
// 获取包名
public abstract String getPackageName();
// 获取应用信息
public abstract ApplicationInfo getApplicationInfo();
// 获取文件存储SharedPreference
@Deprecated
public File getSharedPrefsFile(String name) {
return getSharedPreferencesPath(name);
}
public abstract SharedPreferences getSharedPreferences(String name, @PreferencesMode int mode);
public abstract SharedPreferences getSharedPreferences(File file, @PreferencesMode int mode);
// 移除文件存储SharedPreference
public abstract boolean moveSharedPreferencesFrom(Context sourceContext, String name);
// 删除文件存储SharedPreference
public abstract boolean deleteSharedPreferences(String name);
// 文件输入输出流
public abstract FileInputStream openFileInput(String name)
throws FileNotFoundException;
public abstract FileOutputStream openFileOutput(String name, @FileMode int mode)
throws FileNotFoundException;
// 删除文件
public abstract boolean deleteFile(String name);
// 获取文件数据路径
public abstract File getFileStreamPath(String name);
// 获取SharedPreferences文件路径
public abstract File getSharedPreferencesPath(String name);
// 资源文件目录相关
public abstract File getDataDir();
public abstract File getFilesDir();
public abstract File getNoBackupFilesDir();
// 获取手机外置SD卡文件目录
@Nullable
public abstract File getExternalFilesDir(@Nullable String type);
public abstract File[] getExternalFilesDirs(String type);
public abstract File getDir(String name, @FileMode int mode);
// SQLite数据库操作相关
public abstract SQLiteDatabase openOrCreateDatabase(String name,
public abstract SQLiteDatabase openOrCreateDatabase(String name,
public abstract boolean moveDatabaseFrom(Context sourceContext, String name);
public abstract boolean deleteDatabase(String name);
public abstract File getDatabasePath(String name);
public abstract String[] databaseList();
// 与activity相关的函数
public abstract void startActivity(@RequiresPermission Intent intent);
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
public void startActivityAsUser(@RequiresPermission Intent intent, UserHandle user) {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
public abstract void startActivity(@RequiresPermission Intent intent,
@Nullable Bundle options);
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
public void startActivityAsUser(@RequiresPermission Intent intent, @Nullable Bundle options,
UserHandle userId) {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
public void startActivityForResult(
@NonNull String who, Intent intent, int requestCode, @Nullable Bundle options) {
throw new RuntimeException("This method is only implemented for Activity-based Contexts. "
+ "Check canStartActivityForResult() before calling.");
}
public boolean canStartActivityForResult() {
return false;
}
public abstract void startActivities(@RequiresPermission Intent[] intents);
public abstract void startActivities(@RequiresPermission Intent[] intents, Bundle options);
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
public int startActivitiesAsUser(Intent[] intents, Bundle options, UserHandle userHandle) {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
public abstract void startIntentSender(IntentSender intent, @Nullable Intent fillInIntent,
@Intent.MutableFlags int flagsMask, @Intent.MutableFlags int flagsValues,
int extraFlags) throws IntentSender.SendIntentException;
public abstract void startIntentSender(IntentSender intent, @Nullable Intent fillInIntent,
@Intent.MutableFlags int flagsMask, @Intent.MutableFlags int flagsValues,
int extraFlags, @Nullable Bundle options) throws IntentSender.SendIntentException;
//与Broadcast相关的函数
public abstract void sendBroadcast(@RequiresPermission Intent intent);
public abstract void sendBroadcast(@RequiresPermission Intent intent,
@Nullable String receiverPermission);
public abstract void sendBroadcastMultiplePermissions(Intent intent,
String[] receiverPermissions);
...
@Deprecated
@RequiresPermission(allOf = {
android.Manifest.permission.INTERACT_ACROSS_USERS,
android.Manifest.permission.BROADCAST_STICKY
})
public abstract void removeStickyBroadcastAsUser(@RequiresPermission Intent intent,
UserHandle user);
@Nullable
public abstract Intent registerReceiver(@Nullable BroadcastReceiver receiver,
IntentFilter filter);
...
@Nullable
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
public abstract Intent registerReceiverAsUser(BroadcastReceiver receiver,
UserHandle user, IntentFilter filter, @Nullable String broadcastPermission,
@Nullable Handler scheduler);
public abstract void unregisterReceiver(BroadcastReceiver receiver);
// 与Service相关
@Nullable
public abstract ComponentName startService(Intent service);
// 启动前台Service
@Nullable
public abstract ComponentName startForegroundService(Intent service);
@Nullable
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
public abstract ComponentName startForegroundServiceAsUser(Intent service, UserHandle user);
public abstract boolean stopService(Intent service);
@Nullable
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
public abstract ComponentName startServiceAsUser(Intent service, UserHandle user);
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
public abstract boolean stopServiceAsUser(Intent service, UserHandle user);
public abstract boolean bindService(@RequiresPermission Intent service,
@NonNull ServiceConnection conn, @BindServiceFlags int flags);
@SystemApi
@SuppressWarnings("unused")
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
public boolean bindServiceAsUser(@RequiresPermission Intent service, ServiceConnection conn,
int flags, UserHandle user) {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
Handler handler, UserHandle user) {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
public abstract void unbindService(@NonNull ServiceConnection conn);
public abstract boolean startInstrumentation(@NonNull ComponentName className,
@Nullable String profileFile, @Nullable Bundle arguments);
// 系统相关
public abstract @Nullable Object getSystemService(@ServiceName @NonNull String name);
public final @Nullable <T> T getSystemService(@NonNull Class<T> serviceClass) {
String serviceName = getSystemServiceName(serviceClass);
return serviceName != null ? (T)getSystemService(serviceName) : null;
}
public abstract @Nullable String getSystemServiceName(@NonNull Class<?> serviceClass);
// 检查权限
@CheckResult(suggest="#enforcePermission(String,int,int,String)")
@PackageManager.PermissionResult
public abstract int checkPermission(@NonNull String permission, int pid, int uid);
/** @hide */
@PackageManager.PermissionResult
public abstract int checkPermission(@NonNull String permission, int pid, int uid,
IBinder callerToken);
...
public abstract Context createPackageContext(String packageName,
@CreatePackageOptions int flags) throws PackageManager.NameNotFoundException;
...
}
2.Context有什么用
通过前面的源码我们可以看出Context的重要性,不但Android四大组件中的两个Activity和Service是其子类,而且四大组件的工作过程都与Context密切相关。Activity依赖Context的StartActivity系列函数去启动新的Activity,Service的整个生命周期函数都继承自Context,BroadcastReceiver的静态注册和注销以及发送各种类型的广播都依赖Context,内容提供者ContentProvider实例也需要通过Context去获取。除此之外,Context还提供了操作SQLite数据库,获取各类资源文件信息,获取应用相关的各种存储数据,以及获取应用的基本信息,还有检查各种权限的操作。总之,Context可以理解为Android应用的大总管,负责向Android应用提供各种服务。
附:Context的作用域
[图片上传中...(context的作用域.jpg-49fdc5-1561801607830-0)]
从上图我们可以发现Activity所持有的Context的作用域最广,无所不能。因为Activity继承自ContextThemeWrapper,而Application和Service继承自ContextWrapper,很显然ContextThemeWrapper在ContextWrapper的基础上又做了一些功能的扩展,使得其子类Activity更加强大。
参考文章:https://mp.weixin.qq.com/s/fmAPlgmqeHz0HRB6FTwRdg