(设计模式)接口代理实现Application的多继承

在工作中碰到一个场景,就是你APP的Application是需要继承自家的Application,但是你在接入别人的SDK时,有的sdk接入要求你的Application继承他家的Application,这就比较尴尬了.Java只能单继承这可怎么是好?
接口代理就可以用上了.
首先我们让清单文件声明的Multiapplication继承代理类ProxyApplication,通过super.的方式在对用的生命周期中调用代理类的对应方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/** 
* @author huyuxin
* @date :2017-2-23
* @version 1.0
* @parameter 使用接口代理实现application的多继承
* @since
* @return
*/
public class Multiapplication extends ProxyApplication {

private static final String TAG = Multiapplication.class.getSimpleName();

@Override
public void attachBaseContext(Context base){
super.attachBaseContext(base);
Log.d(TAG, "attachBaseContext");
}

@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d(TAG, "onConfigurationChanged");
}

}

在代理类ProxyApplication 中我们通过反射和接口回调的方式调用实现类ImplementApplication的对应方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/** 
* @author huyuxin
* @date :2017-2-23
* @version 1.0
* @parameter
* @since
* @return
*/
public class ProxyApplication extends Application {

private IApplicationListener listener;


@Override
public void attachBaseContext(Context base){
super.attachBaseContext(base);
this.listener = initProxyApplication();
if(this.listener != null){
this.listener.onProxyAttachBaseContext(base);
}
}

@Override
public void onCreate() {
super.onCreate();
if(listener != null){
listener.onProxyCreate();
}
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if(this.listener != null){
this.listener.onProxyConfigurationChanged(newConfig);
}
}

private IApplicationListener initProxyApplication() {
try {
Class clazz = Class.forName("cn.app.ImplementApplication");
return (IApplicationListener)clazz.newInstance();

} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {

e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}

return null;
}
}

在实现类ImplementApplication中我们还是用接口回调加代理的方式来调用调用我们要继承的多个Appliction的生命周期方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/** 
* @author huyuxin
* @date :2017-2-23
* @version 1.0
* @parameter
* @since
* @return
*/
public class ImplementApplication extends Application implements IApplicationListener {

private IFishApplicationListener fishApplicationListener;
private IEgameApplicationListener egameApplicationListener;


@Override
public void onProxyAttachBaseContext(Context base) {
super.attachBaseContext(base);
this.fishApplicationListener = initFishApplication();

if(this.fishApplicationListener != null){
this.fishApplicationListener.onFishAttachBaseContext(base);
}

this.egameApplicationListener = initEgameApplication();
if(this.egameApplicationListener != null){
this.egameApplicationListener.onEgameAttachBaseContext(base);
}
}

@Override
public void onProxyCreate() {
super.onCreate();
if (fishApplicationListener != null) {
fishApplicationListener.onFishCreate();
}

if (egameApplicationListener != null) {
egameApplicationListener.onEgameCreate();
}
}

@Override
public void onProxyConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if(this.fishApplicationListener != null){
this.fishApplicationListener.onFishConfigurationChanged(newConfig);
}
this.egameApplicationListener = initEgameApplication();

if(this.egameApplicationListener != null){
this.egameApplicationListener.onEgameConfigurationChanged(newConfig);
}
}

private IFishApplicationListener initFishApplication() {
try {
Class clazz = Class.forName("cn.app.ImplementFishApplication");
return (IFishApplicationListener)clazz.newInstance();

} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {

e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}

return null;
}

private IEgameApplicationListener initEgameApplication() {
try {
Class clazz = Class.forName("cn.app.ImplementEgameApplication");
return (IEgameApplicationListener)clazz.newInstance();

} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {

e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}

return null;
}
}

然后就到了最让我们兴奋的时候了,我们可以使用ImplementFishApplication和ImplementEgameApplication两个类来分别继承不同的Application

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/** 
* @author huyuxin
* @date :2017-2-23
* @version 1.0
* @parameter
* @since
* @return
*/
public class ImplementFishApplication extends FishApplication implements IFishApplicationListener {

@Override
public void onFishAttachBaseContext(Context base) {
super.attachBaseContext(base);
}

@Override
public void onFishCreate() {
super.onCreate();
}

@Override
public void onFishConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/** 
* @author huyuxin
* @date :2017-2-23
* @version 1.0
* @parameter
* @since
* @return
*/
public class ImplementEgameApplication extends EgameApplication implements IEgameApplicationListener {
@Override
public void onEgameCreate() {
super.onCreate();
}

@Override
public void onEgameAttachBaseContext(Context base) {
super.attachBaseContext(base);
}

@Override
public void onEgameConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}


}

至此我们只要将Multiapplication 声明在清单文件中就可以实现同时继承并跑EgameApplication 和FishApplication 的生命周期了,各SDK的初始化也一并得到运行.

补充:各个接口都是声明一样的方法

1
2
3
4
5
6
7
8
public interface IEgameApplicationListener {

public void onEgameCreate();

public void onEgameAttachBaseContext(Context base);

public void onEgameConfigurationChanged(Configuration newConfig);
}
1
2
3
4
5
6
7
8
public interface IFishApplicationListener {

public void onFishHunterCreate();

public void onFishHunterAttachBaseContext(Context base);

public void onFishHunterConfigurationChanged(Configuration newConfig);
}
1
2
3
4
5
6
7
8
public interface IApplicationListener {
public void onProxyCreate();

public void onProxyAttachBaseContext(Context base);

public void onProxyConfigurationChanged(Configuration newConfig);

}
您的一份奖励,就是我的一份激励