接口代理实现 Android Application 的多继承

接口代理实现 Android Application 的多继承

在项目开发中,当我们接入第三方 SDK 时,可能会要求我们自己的 Application 继承它们的 Application , 但是 Java 只能是单继承的,这时我们就可以使用接口代理的方式来间接地实现“多继承”了。

假设我们的 MyApplication 需要继承两个第三方 SDK 的类 XApplication 与 YApplication .(本文以百度地图BmfMapApplication和FlutterApplication为例)

显然,我们自家的 MyApplication 是不可能同时直接继承上面的两个 Application 的。我们可以让 MyApplication 继承一个代理类 ProxyApplication , 然后在 ProxyApplication 中通过反射和接口回调的方式调用组合实现类 ApplicationImpl(组合了多个 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
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
package top.w2gd.wit_niit;

import android.content.Context;
import android.content.res.Configuration;
import android.util.Log;

public class MyApplication extends ProxyApplication {

@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);

Log.d("info-->", "MyApplication attachBaseContext");
}

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

Log.d("info-->", "MyApplication onCreate");
}

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

Log.d("info-->", "MyApplication onConfigurationChanged");
}
}
package top.w2gd.wit_niit;

import android.app.Application;
import android.content.Context;
import android.content.res.Configuration;

public class ProxyApplication extends Application {

private IApplicationListener iApplicationListener;

@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);

iApplicationListener = getProxyApplication();

if (iApplicationListener != null) {
iApplicationListener.onProxyAttachBaseContext(base);
}
}

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

if (iApplicationListener != null) {
iApplicationListener.onProxyCreate();
}
}

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

if (iApplicationListener != null) {
iApplicationListener.onProxyConfigurationChanged(newConfig);
}
}

private IApplicationListener getProxyApplication() {
try {
Class clazz = Class.forName("top.w2gd.wit_niit.ApplicationImpl");
return (IApplicationListener) clazz.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}

在组合实现类 ApplicationImpl 中,我们通过反射代理的方式调用多个 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
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
package top.w2gd.wit_niit;

import android.app.Application;
import android.content.Context;
import android.content.res.Configuration;

public class ApplicationImpl extends Application implements IApplicationListener {

private IXApplicationListener ixApplicationListener;
private IYApplicationListener iyApplicationListener;

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

ixApplicationListener = getXApplication();
iyApplicationListener = getYApplication();

if (ixApplicationListener != null) {
ixApplicationListener.onXAttachBaseContext(base);
}
if (iyApplicationListener != null) {
iyApplicationListener.onYAttachBaseContext(base);
}
}

@Override
public void onProxyCreate() {
super.onCreate();

if (ixApplicationListener != null) {
ixApplicationListener.onXCreate();
}
if (iyApplicationListener != null) {
iyApplicationListener.onYCreate();
}
}

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

if (ixApplicationListener != null) {
ixApplicationListener.onXConfigurationChanged(newConfig);
}
if (iyApplicationListener != null) {
iyApplicationListener.onYConfigurationChanged(newConfig);
}
}

private IXApplicationListener getXApplication() {
Class clazz = null;
try {
clazz = Class.forName("top.w2gd.wit_niit.XApplicationImpl");
return (IXApplicationListener) clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}

private IYApplicationListener getYApplication() {
Class clazz = null;
try {
clazz = Class.forName("top.w2gd.wit_niit.YApplicationImpl");
return (IYApplicationListener) clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}

接口 IApplicationListener

1
2
3
4
5
6
7
8
9
10
11
12
13
package top.w2gd.wit_niit;

import android.content.Context;
import android.content.res.Configuration;

public interface IApplicationListener {

void onProxyAttachBaseContext(Context base);

void onProxyCreate();

void onProxyConfigurationChanged(Configuration newConfig);
}

实现类 XApplicationImpl

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
package top.w2gd.wit_niit;

import android.content.Context;
import android.content.res.Configuration;

import com.baidu.mapapi.base.BmfMapApplication;

public class XApplicationImpl extends BmfMapApplication implements IXApplicationListener {


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

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

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

接口 IXApplicationListener

1
2
3
4
5
6
7
8
9
10
11
12
13
package top.w2gd.wit_niit;

import android.content.Context;
import android.content.res.Configuration;

public interface IXApplicationListener {

void onXAttachBaseContext(Context base);

void onXCreate();

void onXConfigurationChanged(Configuration newConfig);
}

实现类 YApplicationImpl

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
package top.w2gd.wit_niit;

import android.content.Context;
import android.content.res.Configuration;

import cn.leancloud.LCLogger;
import cn.leancloud.LeanCloud;
import cn.leancloud.im.LCIMOptions;
import io.flutter.app.FlutterApplication;

public class YApplicationImpl extends FlutterApplication implements IYApplicationListener {
private static final String LC_App_Id = "DtL8wv4T5fXStZXc3Vu8b1Ov-gzGzoHsz";
private static final String LC_App_Key = "AcSQcHf3pkFPCDKQP27CSWwu";
private static final String LC_Server_Url = "https://niit.w2gd.top";

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

@Override
public void onYCreate() {
super.onCreate();
LCIMOptions.getGlobalOptions().setUnreadNotificationEnabled(true);

LeanCloud.setLogLevel(LCLogger.Level.DEBUG);
LeanCloud.initialize(this, LC_App_Id, LC_App_Key, LC_Server_Url);
}

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

接口 IYApplicationListener

1
2
3
4
5
6
7
8
9
10
11
12
package top.w2gd.wit_niit;

import android.content.Context;
import android.content.res.Configuration;

public interface IYApplicationListener {
void onYAttachBaseContext(Context base);

void onYCreate();

void onYConfigurationChanged(Configuration newConfig);
}

当我们在清单文件中声明了 MyApplication 并跑起项目时,会打印以下日志:

08-03 13:56:33.830 9314-9314/? D/info–>: XApplication attachBaseContext
08-03 13:56:33.830 9314-9314/? D/info–>: YApplication attachBaseContext
08-03 13:56:33.830 9314-9314/? D/info–>: MyApplication attachBaseContext
08-03 13:56:33.830 9314-9314/? D/info–>: XApplication onCreate
08-03 13:56:33.830 9314-9314/? D/info–>: YApplication onCreate
08-03 13:56:33.830 9314-9314/? D/info–>: MyApplication onCreate
说明我们在 MyApplication 中成功地调用了 XApplication 与 YApplication 中的生命周期方法。