动态地给一个对象添加一些额外的职责。装饰模式比子类就增长功能来讲更为灵活。java
定义了一个接口,定义了一个sing的方法bash
public interface Component {
void sing();
}
复制代码
定义了具体的被装饰者,实现了Component接口app
public class ConcreteComponent implements Component {
@Override
public void sing() {
System.out.print("sing....");
}
}
复制代码
定义了抽象装饰者,内部持有被装饰者的引用,才能操做被装饰者ide
public abstract class Decorator implements Component {
private Component mComponent;
public Decorator(Component component) {
this.mComponent = component;
}
@Override
public void sing() {
mComponent.sing();
}
}
复制代码
定义了具体的装饰者,能够在方法内作一些功能扩展的工做。ui
public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
//先交钱,后唱歌(添加了收费的功能)
@Override
public void sing() {
System.out.print("先交钱....");
super.sing();
}
}
复制代码
public class DecoratorTest {
public static void main(String[] args){
Component component = new ConcreteComponent();
Decorator decorator = new ConcreteDecorator(component);
decorator.sing();
}
}
复制代码
public class ConcreteDecorator2 extends Decorator{
public ConcreteDecorator2(Component component) {
super(component);
}
@Override
public void sing() {
System.out.print("奏乐....");
super.sing();
}
}
复制代码
public class DecoratorTest {
public static void main(String[] args){
Component component = new ConcreteComponent();
Decorator decorator = new ConcreteDecorator2(component);
decorator.sing();
}
}
复制代码
更换了一个装饰者,提供了一些其余功能,方便装饰者的更换。this
public abstract class Context {
......
public abstract void startActivity(Intent var1);
public abstract void startActivity(Intent var1, @RecentlyNullable Bundle var2);
......
}
复制代码
Context做为抽象基本,定义了四大组件启动、获取资源、类加载、文件管理、权限管理等等抽象方法spa
class ContextImpl extends Context {
......
@Override
public void startActivities(Intent[] intents, Bundle options) {
warnIfCallingFromSystemProcess();
if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
throw new AndroidRuntimeException(
"Calling startActivities() from outside of an Activity "
+ " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
+ " Is this really what you want?");
}
mMainThread.getInstrumentation().execStartActivities(
getOuterContext(), mMainThread.getApplicationThread(), null,
(Activity) null, intents, options);
}
......
}
复制代码
ContextImpl做为被装饰者,内部定义了Activity启动等方法的具体实现code
public class ContextWrapper extends Context {
Context mBase;
public ContextWrapper(Context base) {
mBase = base;
}
//获取被装饰者ContextImpl的引用
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
......
@Override
public void startActivities(Intent[] intents) {
mBase.startActivities(intents);
}
@Override
public void startActivities(Intent[] intents, Bundle options) {
//内部调用的仍是ContextImpl的方法
mBase.startActivities(intents, options);
}
......
}
复制代码
ContextWrapper做为装饰者的基类,持有被装饰者ContextImpl的引用,并在自身的方法内部调用ContextImpl中的逻辑component
ActivityThread:orm
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
......
}
复制代码
经过调用LoadedApk的makeApplication方法建立了Application实例对象。
LoadedApk:
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
......
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
......
}
复制代码
建立了被装饰者ContextImpl对象,而后调用了Instrumentation的newApplication方法建立了Application。
Instrumentation:
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
复制代码
经过调用Application(装饰者)的attach方法,将ContextImpl对象传入。
final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
复制代码
经过调用装饰基类ContextWrapper的attachBaseContext方法来将ContextImpl对象传入,而后对被装饰者进行操做。
ActivityThread:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
//(1)建立了ContextImpl
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
//(2) 建立Activity对象
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
......
if (activity != null) {
appContext.setOuterContext(activity);
//(3)将ContextImpl传入到Activity中
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback);
......
return activity;
}
}
}
复制代码
调用了Activity的attach方法: Activity:
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback) {
attachBaseContext(context);
......
}
复制代码
完成了ContextImpl的建立,并传入到Activity中
Service的启动最后调用到了ActivityThread的handleCreateService方法 ActivityThread:
private void handleCreateService(CreateServiceData data) {
......
Service service = null;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
//(1)service建立
service = (Service) cl.loadClass(data.info.name).newInstance();
......
//(2)ContextImpl建立
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
//(3)ContextImpl传入
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
service.onCreate();
......
}
}
复制代码
Service:
public final void attach(
Context context,
ActivityThread thread, String className, IBinder token,
Application application, Object activityManager) {
attachBaseContext(context);
......
}
复制代码
完成了Service建立和ContextImpl的传入