装饰模式(包装模式)—结构型
结构型简介
结构型模式主要总结了一些类或对象组合在一起的经典结构,这些经典的结构可以解决特定应用场景的问题。结构型模式包括:代理模式、桥接模式、装饰器模式、适配器模式、门面模式、组合模式、享元模式。
简介
装饰模式(Decorator Pattern)主要解决继承过于复杂的问题,通过组合来替代继承;也就是说是继承关系的一种替代方案之一;
UML图
UML图中各个部分代表的含义如下:
组件类
public abstract class Component {
public abstract void operate();
}
组件具体实现类
public class ConcreteComponent extends Component {
@Override
public void operate() {
}
}
抽象装饰类(如果装饰逻辑单一,只有一个的情况下我们可以省略该抽象类,直接是具体的装饰者)
public abstract class Decorator extends Component {
private Component mComponent;
public Decorator(Component mComponent) {
this.mComponent = mComponent;
}
@Override
public void operate() {
mComponent.operate();
}
}
抽象装饰类具体实现类
public class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component mComponent) {
super(mComponent);
}
@Override
public void operate() {
operateA();
super.operate();
operateB();
}
public void operateA() {
}
public void operateB() {
}
}
装饰模式在生活中无处不在,比如说牙膏包装盒,人各种穿着,不管怎么包装但是,人还是那个人本质没有变;
学过Java语言的熟悉IO流,BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter,DataInputStream,DataOutputStream;都是装饰者,都是对装饰设计模式的运用;感兴趣的可以自行查看源码;
JDK源码中的运用
下面以BufferedReader为例粘贴部分源码:
Writer:相当于UML图中的组件类
public abstract class Writer implements Appendable, Closeable, Flushable {
protected Object lock;
protected Writer() {
lock = this;
}
protected Writer(Object lock) {
if (lock == null) {
throw new NullPointerException("lock == null");
}
this.lock = lock;
}
public abstract void close() throws IOException;
public abstract void flush() throws IOException;
public void write(char[] buf) throws IOException {
write(buf, 0, buf.length);
}
public abstract void write(char[] buf, int offset, int count) throws IOException;
public void write(int oneChar) throws IOException {
synchronized (lock) {
char[] oneCharArray = new char[1];
oneCharArray[0] = (char) oneChar;
write(oneCharArray);
}
}
public void write(String str) throws IOException {
write(str, 0, str.length());
}
public void write(String str, int offset, int count) throws IOException {
if ((offset | count) < 0 || offset > str.length() - count) {
throw new StringIndexOutOfBoundsException(str, offset, count);
}
char[] buf = new char[count];
str.getChars(offset, offset + count, buf, 0);
synchronized (lock) {
write(buf, 0, buf.length);
}
}
public Writer append(char c) throws IOException {
write(c);
return this;
}
public Writer append(CharSequence csq) throws IOException {
if (csq == null) {
csq = "null";
}
write(csq.toString());
return this;
}
public Writer append(CharSequence csq, int start, int end) throws IOException {
if (csq == null) {
csq = "null";
}
write(csq.subSequence(start, end).toString());
return this;
}
boolean checkError() {
return false;
}
}
FileWriter(OutputStreamWriter或者其他具体实现类):相当于组件具体实现类(OutputStreamWriter 继承Writer)
public class FileWriter extends OutputStreamWriter {
public FileWriter(File file) throws IOException {
super(new FileOutputStream(file));
}
public FileWriter(File file, boolean append) throws IOException {
super(new FileOutputStream(file, append));
}
public FileWriter(FileDescriptor fd) {
super(new FileOutputStream(fd));
}
public FileWriter(String filename) throws IOException {
super(new FileOutputStream(new File(filename)));
}
public FileWriter(String filename, boolean append) throws IOException {
super(new FileOutputStream(filename, append));
}
}
BufferedWriter:相当于UML图中的具体装饰类(BufferedWriter内部持有了Writer的引用)
public class BufferedWriter extends Writer {
private Writer out;
private char[] buf;
private int pos;
public BufferedWriter(Writer out) {
this(out, 8192);
}
public BufferedWriter(Writer out, int size) {
super(out);
if (size <= 0) {
throw new IllegalArgumentException("size <= 0");
}
this.out = out;
this.buf = new char[size];
}
@Override
public void close() throws IOException {
synchronized (lock) {
if (isClosed()) {
return;
}
Throwable thrown = null;
try {
flushInternal();
} catch (Throwable e) {
thrown = e;
}
buf = null;
try {
out.close();
} catch (Throwable e) {
if (thrown == null) {
thrown = e;
}
}
out = null;
if (thrown != null) {
SneakyThrow.sneakyThrow(thrown);
}
}
}
@Override
public void flush() throws IOException {
synchronized (lock) {
checkNotClosed();
flushInternal();
out.flush();
}
}
private void checkNotClosed() throws IOException {
if (isClosed()) {
throw new IOException("BufferedWriter is closed");
}
}
private void flushInternal() throws IOException {
if (pos > 0) {
out.write(buf, 0, pos);
}
pos = 0;
}
private boolean isClosed() {
return out == null;
}
public void newLine() throws IOException {
write(System.lineSeparator());
}
@Override
public void write(char[] buffer, int offset, int count) throws IOException {
synchronized (lock) {
checkNotClosed();
if (buffer == null) {
throw new NullPointerException("buffer == null");
}
Arrays.checkOffsetAndCount(buffer.length, offset, count);
if (pos == 0 && count >= this.buf.length) {
out.write(buffer, offset, count);
return;
}
int available = this.buf.length - pos;
if (count < available) {
available = count;
}
if (available > 0) {
System.arraycopy(buffer, offset, this.buf, pos, available);
pos += available;
}
if (pos == this.buf.length) {
out.write(this.buf, 0, this.buf.length);
pos = 0;
if (count > available) {
offset += available;
available = count - available;
if (available >= this.buf.length) {
out.write(buffer, offset, available);
return;
}
System.arraycopy(buffer, offset, this.buf, pos, available);
pos += available;
}
}
}
}
@Override
public void write(int oneChar) throws IOException {
synchronized (lock) {
checkNotClosed();
if (pos >= buf.length) {
out.write(buf, 0, buf.length);
pos = 0;
}
buf[pos++] = (char) oneChar;
}
}
@Override
public void write(String str, int offset, int count) throws IOException {
synchronized (lock) {
checkNotClosed();
if (count <= 0) {
return;
}
if (offset < 0 || offset > str.length() - count) {
throw new StringIndexOutOfBoundsException(str, offset, count);
}
if (pos == 0 && count >= buf.length) {
char[] chars = new char[count];
str.getChars(offset, offset + count, chars, 0);
out.write(chars, 0, count);
return;
}
int available = buf.length - pos;
if (count < available) {
available = count;
}
if (available > 0) {
str.getChars(offset, offset + available, buf, pos);
pos += available;
}
if (pos == buf.length) {
out.write(this.buf, 0, this.buf.length);
pos = 0;
if (count > available) {
offset += available;
available = count - available;
if (available >= buf.length) {
char[] chars = new char[count];
str.getChars(offset, offset + available, chars, 0);
out.write(chars, 0, available);
return;
}
str.getChars(offset, offset + available, buf, pos);
pos += available;
}
}
}
}
}
在Android源码也有对装饰模式的运用
Context类做Android的都不陌生,毫不夸张的说几乎每天都在用,四大组件每个里面都有他的直接或间接的引用到;Context本质上是一个抽象类,在装饰设计模式相当于抽象组件,在其内部定义了大量的抽象方法,比如我经常用到的startService和startActivity方法。通过查看Context源码是不是感觉很多方法很熟悉;
package android.content;
//省略很多方法和其他包名等
public abstract class Context {
public abstract AssetManager getAssets();
public abstract Resources getResources();
public abstract Looper getMainLooper();
@NonNull
public final CharSequence getText(@StringRes int resId) {
return getResources().getText(resId);
}
@NonNull
public final String getString(@StringRes int resId) {
return getResources().getString(resId);
}
@NonNull
public final String getString(@StringRes int resId, Object... formatArgs) {
return getResources().getString(resId, formatArgs);
}
@ColorInt
public final int getColor(@ColorRes int id) {
return getResources().getColor(id, getTheme());
}
@Nullable
public final Drawable getDrawable(@DrawableRes int id) {
return getResources().getDrawable(id, getTheme());
}
@NonNull
public final ColorStateList getColorStateList(@ColorRes int id) {
return getResources().getColorStateList(id, getTheme());
}
public abstract void setTheme(@StyleRes int resid);
@ViewDebug.ExportedProperty(deepExport = true)
public abstract Resources.Theme getTheme();
public abstract ClassLoader getClassLoader();
public abstract String getPackageName();
@UnsupportedAppUsage
public abstract String getBasePackageName();
@NonNull
public String getOpPackageName() {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
/** Return the full application info for this context's package. */
public abstract ApplicationInfo getApplicationInfo();
public abstract String getPackageResourcePath();
public abstract String getPackageCodePath();
@Deprecated
@UnsupportedAppUsage
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);
public abstract boolean moveSharedPreferencesFrom(Context sourceContext, String name);
public abstract boolean deleteSharedPreferences(String name);
/** @hide */
public abstract void reloadSharedPreferences();
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);
public abstract File getSharedPreferencesPath(String name);
public abstract File getDataDir();
public abstract File getFilesDir();
public abstract File getNoBackupFilesDir();
@Nullable
public abstract File getExternalFilesDir(@Nullable String type);
public abstract File getObbDir();
public abstract File[] getObbDirs();
public abstract File getCacheDir();
public abstract File getCodeCacheDir();
@Nullable
public abstract File getExternalCacheDir();
@Nullable
@SystemApi
public abstract File getPreloadsFileCache();
public abstract File[] getExternalCacheDirs();
public abstract File[] getExternalMediaDirs();
public abstract String[] fileList();
public abstract File getDir(String name, @FileMode int mode);
public abstract SQLiteDatabase openOrCreateDatabase(String name,
@DatabaseMode int mode, CursorFactory factory);
public abstract SQLiteDatabase openOrCreateDatabase(String name,
@DatabaseMode int mode, CursorFactory factory,
@Nullable DatabaseErrorHandler errorHandler);
public abstract void startActivity(@RequiresPermission Intent intent);
public abstract void startActivity(@RequiresPermission Intent intent,
@Nullable Bundle options);
@UnsupportedAppUsage
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 abstract void startActivities(@RequiresPermission Intent[] intents);
public abstract void startActivities(@RequiresPermission Intent[] intents, Bundle options);
public abstract void sendBroadcast(@RequiresPermission Intent intent);
public abstract void sendBroadcast(@RequiresPermission Intent intent,
@Nullable String receiverPermission);
@SystemApi
public abstract void sendBroadcast(Intent intent,
@Nullable String receiverPermission,
@Nullable Bundle options);
@UnsupportedAppUsage
public abstract void sendBroadcast(Intent intent,
String receiverPermission, int appOp);
public abstract void sendOrderedBroadcast(@RequiresPermission Intent intent,
@Nullable String receiverPermission);
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);
@SystemApi
public abstract void sendOrderedBroadcast(@NonNull Intent intent,
@Nullable String receiverPermission, @Nullable Bundle options,
@Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler,
int initialCode, @Nullable String initialData, @Nullable Bundle initialExtras);
@Nullable
public abstract Intent registerReceiver(@Nullable BroadcastReceiver receiver,
IntentFilter filter);
@Nullable
public abstract Intent registerReceiver(@Nullable BroadcastReceiver receiver,
IntentFilter filter,
@RegisterReceiverFlags int flags);
@Nullable
public abstract Intent registerReceiver(BroadcastReceiver receiver,
IntentFilter filter, @Nullable String broadcastPermission,
@Nullable Handler scheduler);
@Nullable
public abstract Intent registerReceiver(BroadcastReceiver receiver,
IntentFilter filter, @Nullable String broadcastPermission,
@Nullable Handler scheduler, @RegisterReceiverFlags int flags);
@Nullable
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
@UnsupportedAppUsage
public abstract Intent registerReceiverAsUser(BroadcastReceiver receiver,
UserHandle user, IntentFilter filter, @Nullable String broadcastPermission,
@Nullable Handler scheduler);
public abstract void unregisterReceiver(BroadcastReceiver receiver);
@Nullable
public abstract ComponentName startService(Intent service);
@Nullable
public abstract ComponentName startForegroundService(Intent service);
public abstract boolean stopService(Intent service);
@Nullable
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
@UnsupportedAppUsage
public abstract ComponentName startServiceAsUser(Intent service, UserHandle user);
public abstract boolean bindService(@RequiresPermission Intent service,
@NonNull ServiceConnection conn, @BindServiceFlags int flags);
public boolean bindService(@RequiresPermission @NonNull Intent service,
@BindServiceFlags int flags, @NonNull @CallbackExecutor Executor executor,
@NonNull ServiceConnection conn) {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
@UnsupportedAppUsage
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);
/**
* 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 #IPSEC_SERVICE} ("ipsec")
* <dd> A {@link android.net.IpSecManager IpSecManager} for managing IPSec on
* sockets and networks.
* <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.)
*
* <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</code>. Generally, if you are running as an instant app you should always
* check whether the result of this method is {@code null}.
*
* <p>Note: When implementing this method, keep in mind that new services can be added on newer
* Android releases, so if you're looking for just the explicit names mentioned above, make sure
* to return {@code null} when you don't recognize the name — if you throw a
* {@link RuntimeException} exception instead, you're app might break on new Android releases.
*
* @param name The name of the desired service.
*
* @return The service or {@code 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);
@SuppressWarnings("unchecked")
public final @Nullable <T> T getSystemService(@NonNull Class<T> serviceClass) {
String serviceName = getSystemServiceName(serviceClass);
return serviceName != null ? (T)getSystemService(serviceName) : null;
}
@CheckResult(suggest="#enforceUriPermission(Uri,int,int,String)")
@PackageManager.PermissionResult
public abstract int checkUriPermission(Uri uri, int pid, int uid,
@Intent.AccessUriMode int modeFlags);
@PackageManager.PermissionResult
public abstract int checkUriPermission(Uri uri, int pid, int uid,
@Intent.AccessUriMode int modeFlags, IBinder callerToken);
public abstract Context createPackageContext(String packageName,
@CreatePackageOptions int flags) throws PackageManager.NameNotFoundException;
@UnsupportedAppUsage
public abstract Context createApplicationContext(ApplicationInfo application,
@CreatePackageOptions int flags) throws PackageManager.NameNotFoundException;
public abstract Context createContextForSplit(String splitName)
throws PackageManager.NameNotFoundException;
@TestApi
public UserHandle getUser() {
return android.os.Process.myUserHandle();
}
@TestApi
public @UserIdInt int getUserId() {
return android.os.UserHandle.myUserId();
}
public abstract Context createConfigurationContext(
@NonNull Configuration overrideConfiguration);
public abstract Context createDisplayContext(@NonNull Display display);
@SystemApi
public abstract Context createCredentialProtectedStorageContext();
public abstract DisplayAdjustments getDisplayAdjustments(int displayId);
@TestApi
public abstract Display getDisplay();
@TestApi
public abstract int getDisplayId();
public abstract void updateDisplay(int displayId);
public boolean isRestricted() {
return false;
}
public IApplicationThread getIApplicationThread() {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
public Handler getMainThreadHandler() {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
}
其实现类是android.app.ContextImpl,ContextImpl继承Context,并实现了Context中的抽象方法;这里的ContextImpl相当于组件的具体实现类;
class ContextImpl extends Context {
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
@Override
public ComponentName startForegroundService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, true, mUser);
}
@Override
public boolean stopService(Intent service) {
warnIfCallingFromSystemProcess();
return stopServiceCommon(service, mUser);
}
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,
getUser());
}
@Override
public boolean bindService(
Intent service, int flags, Executor executor, ServiceConnection conn) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, null, null, executor, getUser());
}
@Override
public void sendBroadcast(Intent intent) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
intent.prepareToLeaveProcess(this);
ActivityManager.getService().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@Override
public void sendBroadcast(Intent intent, String receiverPermission) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
String[] receiverPermissions = receiverPermission == null ? null
: new String[] {receiverPermission};
try {
intent.prepareToLeaveProcess(this);
ActivityManager.getService().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
null, false, false, getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@Override
public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
String[] receiverPermissions = receiverPermission == null ? null
: new String[] {receiverPermission};
try {
intent.prepareToLeaveProcess(this);
ActivityManager.getService().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
null, true, false, getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
Android中的Activity相比大家都很熟,从继承上说其实也是一个Content,但是Activity不是直接继承Content的,而是继承ContextThemeWrapper;
public class Activity extends ContextThemeWrapper {
@MainThread
@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
}
}
而ContextThemeWrapper又继承ContextWrapper
public class ContextThemeWrapper extends ContextWrapper {
@UnsupportedAppUsage
private int mThemeResource;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768723)
private Resources.Theme mTheme;
@UnsupportedAppUsage
private LayoutInflater mInflater;
private Configuration mOverrideConfiguration;
@UnsupportedAppUsage
private Resources mResources;
}
最终ContextWrapper才继承Context,是不是感觉很复杂,其实这里就是一个典型的装饰模式的运用,ContextWrapper就是我们要找的装饰着,在ContextWrapper中有一个Context的引用。
public class ContextWrapper extends Context {
@UnsupportedAppUsage
Context mBase;
public ContextWrapper(Context base) {
mBase = base;
}
}
我们再看一下ContextWrapper内部的来自于组件的方法;
public class ContextWrapper extends Context {
@Override
public ComponentName startService(Intent service) {
return mBase.startService(service);
}
@Override
public boolean stopService(Intent name) {
return mBase.stopService(name);
}
}
从上面的源码可以看出ContextWrapper中的startService方法也仅仅是调用了组件实现类(ContextImpl)中对应的方法而已,对于具体方法的包装扩展则有ContextWrapper的具体子类完成;比如我们的Service,Activity,Application.
本文地址:https://blog.csdn.net/ezconn/article/details/107128522
上一篇: 5分钟快速集成bugly并测试异常上报
下一篇: 仿抖音上下滑动切换视频