欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

装饰模式(包装模式)—结构型

程序员文章站 2022-03-11 08:23:52
结构型简介结构型模式主要总结了一些类或对象组合在一起的经典结构,这些经典的结构可以解决特定应用场景的问题。结构型模式包括:代理模式、桥接模式、装饰器模式、适配器模式、门面模式、组合模式、享元模式。简介装饰模式(Decorator Pattern)主要解决继承过于复杂的问题,通过组合来替代继承;也就是说是继承关系的一种替代方案之一;UML图组件类public abstract class Component { public abstract void operate()...

结构型简介

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

简介

装饰模式(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 &mdash; 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