接口代理实现 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 中的生命周期方法。