博客
关于我
装饰模式(包装模式)—结构型
阅读量:510 次
发布时间:2019-03-07

本文共 31656 字,大约阅读时间需要 105 分钟。

设计模式主要有23种,大致可分为三类:创建型,机构行,行为型;具体如下:

创建型

结构型

行为型

持续更新中...

 

结构型简介

结构型模式主要总结了一些类或对象组合在一起的经典结构,这些经典的结构可以解决特定应用场景的问题。结构型模式包括:代理模式、桥接模式、装饰器模式、适配器模式、门面模式、组合模式、享元模式。


装饰模式简介

装饰模式(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:     *     * 
*
{@link #WINDOW_SERVICE} ("window") *
The top-level window manager in which you can place custom * windows. The returned object is a {@link android.view.WindowManager}. *
{@link #LAYOUT_INFLATER_SERVICE} ("layout_inflater") *
A {@link android.view.LayoutInflater} for inflating layout resources * in this context. *
{@link #ACTIVITY_SERVICE} ("activity") *
A {@link android.app.ActivityManager} for interacting with the * global activity state of the system. *
{@link #POWER_SERVICE} ("power") *
A {@link android.os.PowerManager} for controlling power * management. *
{@link #ALARM_SERVICE} ("alarm") *
A {@link android.app.AlarmManager} for receiving intents at the * time of your choosing. *
{@link #NOTIFICATION_SERVICE} ("notification") *
A {@link android.app.NotificationManager} for informing the user * of background events. *
{@link #KEYGUARD_SERVICE} ("keyguard") *
A {@link android.app.KeyguardManager} for controlling keyguard. *
{@link #LOCATION_SERVICE} ("location") *
A {@link android.location.LocationManager} for controlling location * (e.g., GPS) updates. *
{@link #SEARCH_SERVICE} ("search") *
A {@link android.app.SearchManager} for handling search. *
{@link #VIBRATOR_SERVICE} ("vibrator") *
A {@link android.os.Vibrator} for interacting with the vibrator * hardware. *
{@link #CONNECTIVITY_SERVICE} ("connection") *
A {@link android.net.ConnectivityManager ConnectivityManager} for * handling management of network connections. *
{@link #IPSEC_SERVICE} ("ipsec") *
A {@link android.net.IpSecManager IpSecManager} for managing IPSec on * sockets and networks. *
{@link #WIFI_SERVICE} ("wifi") *
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. *
{@link #WIFI_AWARE_SERVICE} ("wifiaware") *
A {@link android.net.wifi.aware.WifiAwareManager WifiAwareManager} for management of * Wi-Fi Aware discovery and connectivity. *
{@link #WIFI_P2P_SERVICE} ("wifip2p") *
A {@link android.net.wifi.p2p.WifiP2pManager WifiP2pManager} for management of * Wi-Fi Direct connectivity. *
{@link #INPUT_METHOD_SERVICE} ("input_method") *
An {@link android.view.inputmethod.InputMethodManager InputMethodManager} * for management of input methods. *
{@link #UI_MODE_SERVICE} ("uimode") *
An {@link android.app.UiModeManager} for controlling UI modes. *
{@link #DOWNLOAD_SERVICE} ("download") *
A {@link android.app.DownloadManager} for requesting HTTP downloads *
{@link #BATTERY_SERVICE} ("batterymanager") *
A {@link android.os.BatteryManager} for managing battery state *
{@link #JOB_SCHEDULER_SERVICE} ("taskmanager") *
A {@link android.app.job.JobScheduler} for managing scheduled tasks *
{@link #NETWORK_STATS_SERVICE} ("netstats") *
A {@link android.app.usage.NetworkStatsManager NetworkStatsManager} for querying network * usage statistics. *
{@link #HARDWARE_PROPERTIES_SERVICE} ("hardware_properties") *
A {@link android.os.HardwarePropertiesManager} for accessing hardware properties. *
* *

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.) * *

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 null. Generally, if you are running as an instant app you should always * check whether the result of this method is {@code null}. * *

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 getSystemService(@NonNull Class
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.

转载地址:http://hcvjz.baihongyu.com/

你可能感兴趣的文章
msbuild发布web应用程序
查看>>
MSB与LSB
查看>>
MSCRM调用外部JS文件
查看>>
MSCRM调用外部JS文件
查看>>
MSEdgeDriver (Chromium) 不适用于版本 >= 79.0.313 (Canary)
查看>>
MsEdgeTTS开源项目使用教程
查看>>
msf
查看>>
MSSQL数据库查询优化(一)
查看>>
MSSQL日期格式转换函数(使用CONVERT)
查看>>
MSTP多生成树协议(第二课)
查看>>
MSTP是什么?有哪些专有名词?
查看>>
Mstsc 远程桌面链接 And 网络映射
查看>>
Myeclipse常用快捷键
查看>>
MyEclipse用(JDBC)连接SQL出现的问题~
查看>>
myeclipse的新建severlet不见解决方法
查看>>
MyEclipse设置当前行背景颜色、选中单词前景色、背景色
查看>>
myeclipse配置springmvc教程
查看>>
MyEclipse配置SVN
查看>>
MTCNN 人脸检测
查看>>
MyEcplise中SpringBoot怎样定制启动banner?
查看>>