欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Android封裝一個(gè)全局的BaseActivity

 更新時(shí)間:2021年04月09日 17:18:22   作者:還吹著風(fēng)、  
這篇文章主要介紹了詳解Android封裝一個(gè)全局的BaseActivity,對(duì)封裝感興趣的同學(xué),可以參考下

1.前言

  • 對(duì)于一個(gè)Android開發(fā)者來說,每一個(gè)頁面都繼承一個(gè)單獨(dú)的系統(tǒng)Activity,有時(shí)候會(huì)帶來很多不必要的困擾。比如:每一個(gè)頁面會(huì)有重復(fù)的代碼,閱讀起來麻煩;每一次寫新的頁面功能總要打開原來的頁面代碼拷貝一部分過來;有時(shí)候代碼調(diào)試排查問題也不方便等等。
  • 如果你的項(xiàng)目里面沒有將Activity都繼承自一個(gè)自己封裝的BaseActivity、或者針對(duì)自己封裝的BaseActivity覺得還不夠完善的,這篇博客可能會(huì)對(duì)你有幫助!

2.特點(diǎn)

  • 封裝:將所有Activity都用到的一部分代碼封裝到一個(gè)統(tǒng)一管理的Activity類(后面全部起名叫BaseActivity),然后由這個(gè)BaseActivity繼承自Android系統(tǒng)的AppCompatActivity(一般是這個(gè))。
  • 繼承:頁面上用到的Activity都繼承自我們的自己BaseActivity,BaseActivity封裝的方法在Activity內(nèi)直接調(diào)用。

3.代碼及說明

3.1.優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):減少了代碼的重復(fù),提高了寫代碼的效率、以及提高了代碼的維護(hù)性
  • 缺點(diǎn):不要任何代碼都放在BaseActivity,那樣可能會(huì)導(dǎo)致BaseActivity過于臃腫,不利于代碼的閱讀和維護(hù),甚至出現(xiàn)App奔潰

下面會(huì)討論哪些代碼應(yīng)該放在BaseActivity里面,哪些需要謹(jǐn)慎

3.2.代碼

下面我貼一份我自己封裝的BaseActivity,在代碼中和代碼下面做了解釋:

public abstract class BaseActivity extends AppCompatActivity {

    public Activity mActivity;
    private Unbinder mUnbinder;
    private static float sNoncompatDensity;
    private static float sNoncompatScaledDensity;
    private MaterialDialog mDialog;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        onAdjustLayout();
        setContentView(setContentLayout());
        //這里的是初始化綁定ButterKnife,在onDestory做了銷毀
        mUnbinder = ButterKnife.bind(this);
        this.mActivity = this;
        //統(tǒng)一將一個(gè)activity添加到一個(gè)集合里面
        AppManager.getInstance().addActivity(mActivity);
        initToolBar();
        initPresenter();
        initData(savedInstanceState);
        Log.e("app", this.getClass().getSimpleName() + "------onCreate");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.e("app", this.getClass().getSimpleName() + "------onStart");
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.e("app", this.getClass().getSimpleName() + "------onRestoreInstanceState");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.e("app", this.getClass().getSimpleName() + "------onRestart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.e("app", this.getClass().getSimpleName() + "------onResume");
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.e("app", this.getClass().getSimpleName() + "------onSaveInstanceState");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.e("app", this.getClass().getSimpleName() + "------onPause");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.e("app", this.getClass().getSimpleName() + "------onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        onDestroyActivity();
        mUnbinder.unbind();
        Log.e("app", this.getClass().getSimpleName() + "------onDestroy");
    }

    /**
     * 顯示一個(gè)Fragment
     */
    public void showFragment(Fragment fragment) {
        if (fragment != null && fragment.isHidden()) {
            FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            fragmentTransaction.show(fragment);
            fragmentTransaction.commit();
        }
    }

    /**
     * 隱藏一個(gè)Fragment
     */
    public void hideFragment(Fragment fragment) {
        if (fragment != null && !fragment.isHidden()) {
            FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            fragmentTransaction.hide(fragment);
            fragmentTransaction.commit();
        }
    }

	//這是一個(gè)設(shè)置toolbar標(biāo)題欄的方法,ToolBarOptions類主要是持有一些id
    public void setToolBar(int toolBarId, ToolBarOptions options) {
        Toolbar toolbar = findViewById(toolBarId);
        if (options.titleId != 0) {
            toolbar.setTitle(options.titleId);
        } else {
            toolbar.setTitle("");
        }
        if (!TextUtils.isEmpty(options.titleString)) {
            toolbar.setTitle(options.titleString);
        }
        if (options.backgroundColor != 0) {
            toolbar.setBackgroundResource(options.backgroundColor);
        }
        if (options.logoId != 0) {
            toolbar.setLogo(options.logoId);
        }
        setSupportActionBar(toolbar);

        if (options.isNeedNavigate) {
            toolbar.setNavigationIcon(options.navigateId);
            toolbar.setContentInsetStartWithNavigation(0);
            toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (!AppUtils.isNotFastClick()) {
                        return;
                    }
                    onNavigateUpClicked();
                }
            });
        }
    }

	//子類直接調(diào)用展示toast
    public void showToast(String s) {
        ToastUtil.showToast(this, s);
    }

	//給子類提供一個(gè)獲取activity對(duì)象的方式
    public Activity getActivity() {
        return this;
    }

	//一個(gè)彈窗l(fā)oading庫 github地址:
    //implementation 'com.afollestad.material-dialogs:core:0.9.6.0'
    public void showLoading(String loadDesc) {
        mDialog = new MaterialDialog.Builder(this)
                .progress(true, -1)
                .content(loadDesc)
                .canceledOnTouchOutside(false)
                .cancelable(false)
                .show();
    }

    public void showLoading(int resId) {
        mDialog = new MaterialDialog.Builder(this)
                .progress(true, -1)
                .content(getString(resId))
                .canceledOnTouchOutside(false)
                .cancelable(false)
                .show();
    }

    public void showLoading() {
        mDialog = new MaterialDialog.Builder(this)
                .progress(true, -1)
                .content("加載中...")
                .canceledOnTouchOutside(false)
                .cancelable(false)
                .show();
    }

    public void hideLoading() {
        if (mDialog != null) {
            mDialog.dismiss();
        }
    }

	//這里是退出app相關(guān)的邏輯,可以根據(jù)自己的退出做具體的處理
    public void exitLogin() {
        SharedPreferenceUtils.getInstance(mActivity).put(Constant.KEY_LOGIN_TOKEN, "");
        if (mDialog != null) {
            mDialog.hide();
            mDialog = null;
        }
        mDialog = new MaterialDialog.Builder(this)
                .canceledOnTouchOutside(false)
                .title("提示")
                .content("賬號(hào)已在其他地方登錄,請(qǐng)退出重新登錄!")
                .positiveText("確定")
                .onPositive(new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                        AppManager.getInstance().finishAllActivity();
                        Intent intent = new Intent(mActivity, LoginActivity.class);
                        startActivity(intent);
                        finish();
                    }
                }).show();
    }

    private void onNavigateUpClicked() {
        onBackPressed();
    }

    //開始contentLayout前調(diào)整布局(子類若有需要可以單獨(dú)復(fù)寫)
    public void onAdjustLayout() {

    }

	//下面這5個(gè)方法是子類必須實(shí)現(xiàn)的,分別是layout布局、toolbar、mvp的persenter初始化、
	//onCreate內(nèi)的initData、以及頁面銷毀的onDestroyActivity(可以根據(jù)自己的需要添加)
    public abstract int setContentLayout();

    public abstract void initToolBar();

    public abstract void initPresenter();

    public abstract void initData(Bundle savedInstanceState);

    public abstract void onDestroyActivity();
}

3.3.注意點(diǎn)

  • 在BaseActivity的每個(gè)生命周期內(nèi)都有l(wèi)og日志,這里是方便觀察執(zhí)行到activity的哪個(gè)生命周期,logcat也可以簡單封裝一下,統(tǒng)一控制日志是否打印。
  • BaseActivity并不適合每一個(gè)頁面的Activity,比如進(jìn)入應(yīng)用的閃屏頁面,就可以考慮不繼承BaseActivity,因?yàn)檫@個(gè)頁面通常不需要寫太多代碼?;蛘哌€有其他特殊的業(yè)務(wù)場景下。
  • 需要注意一個(gè)Dialog彈窗問題,在BaseActivity里面,每次show一個(gè)dialog的時(shí)候我都是創(chuàng)建一個(gè)新的對(duì)象,那么就要注意dialog在未關(guān)閉之前不能再去show,否則可能會(huì)導(dǎo)致dialog出現(xiàn)異常。但是不要在onDestory方法里面去隱藏dialog彈窗,因?yàn)樵贏頁面進(jìn)入B頁面的時(shí)候,會(huì)先執(zhí)行到B頁面生命周期的onCreate、onStart、onResume三個(gè)方法,然后再執(zhí)行A頁面的onStop可能還有onDestory方法,所以等B頁面加載完成再去銷毀A頁面是錯(cuò)誤的。
  • 有時(shí)候?yàn)榱朔奖憧赡苡腥藭?huì)把請(qǐng)求Android中權(quán)限檢測的方法放在BaseActivity里面,這樣并不是特別合適,因?yàn)樗欣^承自BaseActivity的頁面都會(huì)去檢測權(quán)限,這樣會(huì)導(dǎo)致用戶體驗(yàn)差,所以建議用到權(quán)限的地方再去請(qǐng)求,最好自己封裝一個(gè)工具類,用起來方便一點(diǎn)。
  • BaseActivity的封裝并不強(qiáng)求子類必須實(shí)現(xiàn)activity生命周期相關(guān)的方法,除了幾個(gè)抽象方法(我認(rèn)為子類需要復(fù)寫的,可以根據(jù)業(yè)務(wù)自己定),必要的話可以自己復(fù)寫。

4.總結(jié)

不是很復(fù)雜,寫的也比較詳細(xì),也基本適用于絕大部分的場景。可能還有其他需要注意的細(xì)節(jié)回頭想起來再補(bǔ)上。

以上就是詳解Android封裝一個(gè)全局的BaseActivity的詳細(xì)內(nèi)容,更多關(guān)于Android封裝BaseActivity的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論