为什么要阅读安卓源码,因为安卓源码是google开发的,其中有良好的代码风格和习惯,对于养成良好编码习惯和编程思想有很大的帮助.
但是安卓源码数量庞大,需要从哪里入手?
开发apk下载SDK,下载 Sources for Android 29(大家可以下载自己对应的版本的代码),然后通过Android Stuido 可以打开..\sdk\sources\android-29 对应的目录,可以看见对应的工程.不过这个工程没有办法进行同步,也就是说非本文件内容,点击不会跳转.
这里可以推荐大家使用source insight,这是我最开始接触编程的时候用的功能,它可以实现同步代码.
推荐大家从熟悉的Cotenxt,ContextImpl,ContextWrapper这几个类来看,这几个类中涉及系统服务的注册,获取等等.
下面将从熟悉的Context开始来分析:
- Context是个抽象类,老外对封装用的比较好,经常看到调用这个类.
public abstract class Context {
- Context类开始的地方定义了一些常量数据,用注解定义的,这个平时编程的时候,也可以借鉴一下
/** @hide */
@IntDef(flag = true, prefix = { "MODE_" }, value = {
MODE_PRIVATE,
MODE_WORLD_READABLE,
MODE_WORLD_WRITEABLE,
MODE_APPEND,
})
@Retention(RetentionPolicy.SOURCE)
public @interface FileMode {}
带有@hide是系统需要对应用隐藏的方法或者属性.
定义类型@FileMode注解的类型
public abstract FileOutputStream openFileOutput(String name, @FileMode int mode)
throws FileNotFoundException;
- 定义抽象方法
/**
* 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()
*/
public abstract Resources getResources();
平时使用的时候,就调用context.getResources()就可以,不用关心具体实现的方法.
- final不可重写方法
/**
* Returns a localized string from the application's package's
* default string table.
*
* @param resId Resource id for the string
* @return The string data associated with the resource, stripped of styled
* text information.
*/
@NonNull
public final String getString(@StringRes int resId) {
return getResources().getString(resId);
}
- 比较重要的方法
/**
* Return the handle to a system-level service by class.
* <p>
* Currently available classes are:
* {@link android.view.WindowManager}, {@link android.view.LayoutInflater},
* {@link android.app.ActivityManager}, {@link android.os.PowerManager},
* {@link android.app.AlarmManager}, {@link android.app.NotificationManager},
* {@link android.app.KeyguardManager}, {@link android.location.LocationManager},
* {@link android.app.SearchManager}, {@link android.os.Vibrator},
* {@link android.net.ConnectivityManager},
* {@link android.net.wifi.WifiManager},
* {@link android.media.AudioManager}, {@link android.media.MediaRouter},
* {@link android.telephony.TelephonyManager}, {@link android.telephony.SubscriptionManager},
* {@link android.view.inputmethod.InputMethodManager},
* {@link android.app.UiModeManager}, {@link android.app.DownloadManager},
* {@link android.os.BatteryManager}, {@link android.app.job.JobScheduler},
* {@link android.app.usage.NetworkStatsManager}.
* </p>
*
* <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.)
* </p>
*
* <p>Note: Instant apps, for which {@link PackageManager#isInstantApp()} returns true,
* don't have access to the following system services: {@link #DEVICE_POLICY_SERVICE},
* {@link #FINGERPRINT_SERVICE}, {@link #KEYGUARD_SERVICE}, {@link #SHORTCUT_SERVICE},
* {@link #USB_SERVICE}, {@link #WALLPAPER_SERVICE}, {@link #WIFI_P2P_SERVICE},
* {@link #WIFI_SERVICE}, {@link #WIFI_AWARE_SERVICE}. For these services this method will
* return {@code null}. Generally, if you are running as an instant app you should always
* check whether the result of this method is {@code null}.
* </p>
*
* @param serviceClass The class of the desired service.
* @return The service or {@code null} if the class is not a supported system service. Note:
* <b>never</b> throw a {@link RuntimeException} if the name is not supported.
*/
@SuppressWarnings("unchecked")
public final @Nullable <T> T getSystemService(@NonNull Class<T> serviceClass) {
// Because subclasses may override getSystemService(String) we cannot
// perform a lookup by class alone. We must first map the class to its
// service name then invoke the string-based method.
String serviceName = getSystemServiceName(serviceClass);
return serviceName != null ? (T)getSystemService(serviceName) : null;
}
通过public final @Nullable T getSystemService(@NonNull Class serviceClass) 来获取对应类的服务类,而且不用强制转换.这个地方可以学习一下如何使用泛型定义方法.
- 定义限定范围的String类型
/** @hide */
@StringDef(suffix = { "_SERVICE" }, value = {
POWER_SERVICE,
WINDOW_SERVICE,
LAYOUT_INFLATER_SERVICE,
ACCOUNT_SERVICE,
ACTIVITY_SERVICE,
ALARM_SERVICE,
NOTIFICATION_SERVICE,
ACCESSIBILITY_SERVICE,
CAPTIONING_SERVICE,
KEYGUARD_SERVICE,
LOCATION_SERVICE,
//@hide: COUNTRY_DETECTOR,
SEARCH_SERVICE,
SENSOR_SERVICE,
SENSOR_PRIVACY_SERVICE,
STORAGE_SERVICE,
STORAGE_STATS_SERVICE,
WALLPAPER_SERVICE,
TIME_ZONE_RULES_MANAGER_SERVICE,
VIBRATOR_SERVICE,
//@hide: STATUS_BAR_SERVICE,
CONNECTIVITY_SERVICE,
//@hide: IP_MEMORY_STORE_SERVICE,
IPSEC_SERVICE,
TEST_NETWORK_SERVICE,
//@hide: UPDATE_LOCK_SERVICE,
//@hide: NETWORKMANAGEMENT_SERVICE,
NETWORK_STATS_SERVICE,
//@hide: NETWORK_POLICY_SERVICE,
WIFI_SERVICE,
WIFI_AWARE_SERVICE,
WIFI_P2P_SERVICE,
WIFI_SCANNING_SERVICE,
//@hide: LOWPAN_SERVICE,
//@hide: WIFI_RTT_SERVICE,
//@hide: ETHERNET_SERVICE,
WIFI_RTT_RANGING_SERVICE,
NSD_SERVICE,
AUDIO_SERVICE,
FINGERPRINT_SERVICE,
//@hide: FACE_SERVICE,
BIOMETRIC_SERVICE,
MEDIA_ROUTER_SERVICE,
TELEPHONY_SERVICE,
TELEPHONY_SUBSCRIPTION_SERVICE,
CARRIER_CONFIG_SERVICE,
TELECOM_SERVICE,
CLIPBOARD_SERVICE,
INPUT_METHOD_SERVICE,
TEXT_SERVICES_MANAGER_SERVICE,
TEXT_CLASSIFICATION_SERVICE,
APPWIDGET_SERVICE,
//@hide: VOICE_INTERACTION_MANAGER_SERVICE,
//@hide: BACKUP_SERVICE,
ROLLBACK_SERVICE,
DROPBOX_SERVICE,
//@hide: DEVICE_IDLE_CONTROLLER,
DEVICE_POLICY_SERVICE,
UI_MODE_SERVICE,
DOWNLOAD_SERVICE,
NFC_SERVICE,
BLUETOOTH_SERVICE,
//@hide: SIP_SERVICE,
USB_SERVICE,
LAUNCHER_APPS_SERVICE,
//@hide: SERIAL_SERVICE,
//@hide: HDMI_CONTROL_SERVICE,
INPUT_SERVICE,
DISPLAY_SERVICE,
//@hide COLOR_DISPLAY_SERVICE,
USER_SERVICE,
RESTRICTIONS_SERVICE,
APP_OPS_SERVICE,
ROLE_SERVICE,
//@hide ROLE_CONTROLLER_SERVICE,
CAMERA_SERVICE,
PRINT_SERVICE,
CONSUMER_IR_SERVICE,
//@hide: TRUST_SERVICE,
TV_INPUT_SERVICE,
//@hide: NETWORK_SCORE_SERVICE,
USAGE_STATS_SERVICE,
MEDIA_SESSION_SERVICE,
BATTERY_SERVICE,
JOB_SCHEDULER_SERVICE,
//@hide: PERSISTENT_DATA_BLOCK_SERVICE,
//@hide: OEM_LOCK_SERVICE,
MEDIA_PROJECTION_SERVICE,
MIDI_SERVICE,
RADIO_SERVICE,
HARDWARE_PROPERTIES_SERVICE,
//@hide: SOUND_TRIGGER_SERVICE,
SHORTCUT_SERVICE,
//@hide: CONTEXTHUB_SERVICE,
SYSTEM_HEALTH_SERVICE,
//@hide: INCIDENT_SERVICE,
//@hide: INCIDENT_COMPANION_SERVICE,
//@hide: STATS_COMPANION_SERVICE,
COMPANION_DEVICE_SERVICE,
CROSS_PROFILE_APPS_SERVICE,
//@hide: SYSTEM_UPDATE_SERVICE,
//@hide: TIME_DETECTOR_SERVICE,
PERMISSION_SERVICE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ServiceName {}
public abstract @Nullable Object getSystemService(@ServiceName @NonNull String name);
这样它就可以检查参数的有效性,如果不在定义的范围内,编译不过! 7.