Android开发之路别人的坑bug系列

接口代理实现Application多继承

2019-04-28  本文已影响286人  程序员阿兵

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

/** 
 * @author guiyanbing
 * @date :2019-4-28
 * @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的对应方法:

/** 
 * @author guiyanbing
 * @date :2019-4-28
 * @version 1.0
 * @parameter   使用接口代理实现application的多继承
 * @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的生命周期方法:

/** 
 * @author guiyanbing
 * @date :2019-4-28
 * @version 1.0
 * @parameter   使用接口代理实现application的多继承
 * @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

/** 
 * @author guiyanbing
 * @date :2019-4-28
 * @version 1.0
 * @parameter   使用接口代理实现application的多继承
 * @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);
    }

}


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的初始化也一并得到运行.

public interface IEgameApplicationListener {

    public void onEgameCreate();

    public void onEgameAttachBaseContext(Context base);

    public void onEgameConfigurationChanged(Configuration newConfig);
}


public interface IFishApplicationListener {

    public void onFishHunterCreate();

    public void onFishHunterAttachBaseContext(Context base);

    public void onFishHunterConfigurationChanged(Configuration newConfig);
}


public interface IApplicationListener {
    public void onProxyCreate();

    public void onProxyAttachBaseContext(Context base);

    public void onProxyConfigurationChanged(Configuration newConfig);

}



上一篇 下一篇

猜你喜欢

热点阅读