Android的Base初始化,使用代理模式

概述

首先,我们的项目一般会有很多的Base类,各种类型,风格的Activity,Fragment,或者是Dialog,然后我们的子类去继承它执行一些统一性的初始化工作,比如初始化一些基础控件,一些topbar之类的。然后,对于方法,我们也是回做一个功能单一的抽取,比如initData,initEvent之类的。但是,每一个Base都是用这样的方式会需要重复不少的代码,因此我们考虑使用一个借口抽象这些方法,然后让Base去实现。但是Base的实现,发现我们可以使用更加简洁的方式去避免在各种初始化的方法中做各种判断,想到这个,我们就可以使用代理模式去实现。

实现

接口方法
public interface ComponentsImpl {
    /**
     * 获取布局id
     *
     * @return layout id
     */
    int getLayoutId();

    /**
     * 恢复数据
     *
     * @param savedInstanceState
     */
    void recoverAndBeforeInfalter(@Nullable Bundle savedInstanceState);

    /**
     * initview,data等东西之前处理,比如全屏之类
     */
    void beforeInit();

    /**
     * 初始化事件监听
     */
    void initEvent();

    /**
     * 初始化基本数据
     */
    void initData();

}
代理类

他的作用主要是被代理类和base类实现。
现在有一个比较好用简单的注入框架叫做ButterKnife,我的一般项目都是使用它做View的init,所以我们这里的代理类还负责为每一个Base进行ButterKnife的引入。

/**
 * Created by liweijie on 2016/5/19.
 * 代理模式,代理组件初始化
 */
public class ComponentsImplProxy implements ComponentsImpl {

    private ComponentsImpl components;

    public ComponentsImplProxy(ComponentsImpl components) {
        this.components = components;
    }

    public void init(Bundle savedInstanceState,Object obj) {
        if (components instanceof Activity) {
            ButterKnife.bind((Activity) components);
        }else if(obj instanceof View){
            ButterKnife.bind(components, (View) obj);
        }
        recoverAndBeforeInfalter(savedInstanceState);
        initData();
        initEvent();
    }

    @Override
    public void beforeInit() {
        components.beforeInit();
    }

    @Override
    public void initData() {
        components.initData();
    }

    @Override
    public void initEvent() {
        components.initEvent();
    }

    @Override
    public void recoverAndBeforeInfalter(@Nullable Bundle savedInstanceState) {
        if (savedInstanceState == null) {
            return;
        }
        components.recoverAndBeforeInfalter(savedInstanceState);
    }

    @Override
    public int getLayoutId() {
        int layoutId = components.getLayoutId();
        if (layoutId == 0) {
            L.e("Activity或者是Fragment或者View不能没有layout id");
            throw new IllegalStateException("Activity或者是Fragment或者View不能没有layout id");
        }
        return layoutId;
    }

    /**
     * 释放
     */

    public void destroyComponents() {
        ButterKnife.unbind(components);
        if (components == null) {
            return;
        }
        if (components instanceof Activity) {
            if (!((Activity) components).isFinishing()) {
                ((Activity) components).finish();
            }
        }

        components = null;
    }
}

关于代理模式,大家请先去查看相关资料,简单来讲就是代理类拥有真实角色的引用,然后在代理类里面使用这个引用调用具体实现。我们这里需要注意的是init方法,他是的调用在实际中是在getLayoutId和beforeInit之后的,还可以做类似的判空,不用每一个Base类都去做。
这样子实现的好处就是一个是节省代码,一个是分类管理,易于变化。比如当我们的接口发生变化的时候,我们只是需要改动代理类的调用,而不管Base类的调用,这样子就可以实现单一原则。

具体的Base类

以一个BaseActivity 来讲,他是负责调用代理类的,接口的具体实现是有Base类的子类实现的。

public abstract class BaseActivity extends AppCompatActivity implements ComponentsImpl {
    private ComponentsImplProxy componentsImplProxy;
    protected LG BL;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        componentsImplProxy = new ComponentsImplProxy(this);
        int layoutId = componentsImplProxy.getLayoutId();
        componentsImplProxy.beforeInit();
        setContentView(layoutId);
        // 状态栏处理
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            WindowManager.LayoutParams localLayoutParams = getWindow().getAttributes();
            localLayoutParams.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | localLayoutParams.flags);
        }
        BL = new LG(this.getClass());
        componentsImplProxy.init(savedInstanceState,null);
    }

    @Override
    protected void onStart() {
        super.onStart();
        BL.d("AppCompatActivity onStart");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        BL.d("AppCompatActivity onRestart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        BL.d("AppCompatActivity onResume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        BL.d("AppCompatActivity onPause");
    }

    @Override
    protected void onStop() {
        super.onStop();
        BL.d("AppCompatActivity onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        BL.d("AppCompatActivity onDestroy");
        componentsImplProxy.destroyComponents();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        BL.d("AppCompatActivity onLowMemory");
    }
}

然后具体子类的实现:

public class WelcomeActivity extends BaseActivity {
    @Override
    public void beforeInit() {
        requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//去掉信息栏
    }

    @Override
    public void initData() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(WelcomeActivity.this,
                        GalleryMainActivity.class);
                startActivity(intent);
                finish();
            }
        }, 1500);
    }

    @Override
    public void initEvent() {

    }

    @Override
    public void recoverAndBeforeInfalter(@Nullable Bundle savedInstanceState) {

    }

    @Override
    public int getLayoutId() {
        return R.layout.activity_welcome;
    }


}

以后我们的具体子类就可以继承对应的Base类,这样子我们的项目就有了一个统一的规则,以后不论谁接手都会按照这个规则去做,项目维护起来也是比较的顺利。

我的公众号:
这里写图片描述
请大家关注,大家对于本文的建议也可以提出了指正,thanks。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值