好文:https://www.cnblogs.com/chenxing818/p/4705919.html
1. 一个示例
类的继承关系:
1.1 定义
public interface Person {
void eat();
}
public class Man implements Person {
public void eat() {
System.out.println("男人在吃");
}
}
public abstract class Decorator implements Person {
protected Person person;
public void setPerson(Person person) {
this.person = person;
}
public void eat() {
person.eat();
}
}
public class ManDecorator1 extends Decorator {
public void eat() {
super.eat();
reEat();
System.out.println("ManDecorator1类");
}
public void reEat() {
System.out.println("再吃一顿饭");
}
}
1.2 测试
public class Test {
public static void main(String[] args) {
Man man = new Man();
ManDecorator1 md1 = new ManDecorator1();
md1.setPerson(man);
md1.eat(); //先执行super.eat();即man.eat();,后执行reEat();
}
}
打印:
男人在吃
再吃一顿饭
ManDecorator1类
1.3 总结
装饰者模式的作用:动态地扩展对象的功能(理解:动态主要体现在执行super.eat()时,super可动态地绑定其他对象,此处为man)
2. Android系统中的装饰者模式
类的继承关系:
public class Activity extends ContextThemeWrapper {}
public class ContextThemeWrapper extends ContextWrapper {}
public class ContextWrapper extends Context {}
class ContextImpl extends Context {}
发现也符合装饰者模式,由示例可知有setPerson函数将Man的实例化对象保存到ManDecorator1的成员变量中,因此也有一个函数将ContextImpl的实例化对象保存到Activity的成员变量中
在分析Activity的启动流程中:
frameworks\base\core\java\android\app\ActivityThread.java
public final class ActivityThread {
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ContextImpl appContext = createBaseContextForActivity(r);
activity.attach(appContext, this, getInstrumentation(), r.token, ---------------- //appContext为ContextImpl实例化对象
r.ident, app, r.intent, r.activityInfo, title, r.parent, |
r.embeddedID, r.lastNonConfigurationInstances, config, |
r.referrer, r.voiceInteractor, window, r.configCallback); |
} |
} |
|
frameworks\base\core\java\android\app\Activity.java |
public class Activity extends ContextThemeWrapper |
implements LayoutInflater.Factory2, |
Window.Callback, KeyEvent.Callback, |
OnCreateContextMenuListener, ComponentCallbacks2, |
Window.OnWindowDismissedCallback, WindowControllerCallback, |
AutofillManager.AutofillClient { |
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); ------------------------------------------------------------
... |
} |
protected void attachBaseContext(Context newBase) { <---------------------------------------
super.attachBaseContext(newBase); -----------------------------------
} |
} |
|
frameworks\base\core\java\android\view\ContextThemeWrapper.java |
public class ContextThemeWrapper extends ContextWrapper { |
protected void attachBaseContext(Context newBase) { <--------------------
super.attachBaseContext(newBase); -------------------------------------------------------
} |
} |
|
frameworks\base\core\java\android\content\ContextWrapper.java |
public class ContextWrapper extends Context { |
protected void attachBaseContext(Context base) { <------------------------------------------------
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base; //ContextWrapper.mBase为ContextImpl实例化对象,Activity继承自ContextWrapper,所以Activity.mBase为ContextImpl实例化对象
}
}
因此:
Activity,Service,Application都是ContextWrapper的子类,ContextWrapper里面有一个Context类型的成员变量mBase,当然它实际的类型是ContextImpl
执行Activity.mBase.***()相当于ContextWrapper.mBase.***(),最终执行ContextImpl.***()