Android encapsulates a global BaseActivity

  • 2021-12-12 05:47:02
  • OfStack

1. Preface

For an Android developer, every page inherits a separate system Activity, which sometimes brings a lot of unnecessary troubles. For example, every 1 page will have repeated codes, which is troublesome to read; Every time you write a new page function, you should always open the original page code and copy part 1; Sometimes it is inconvenient to debug and troubleshoot problems. If your project does not inherit Activity from a self-encapsulated BaseActivity, or for their encapsulated BaseActivity that is not perfect enough, this blog may be helpful to you!

2. Features

Encapsulation: Encapsulate 1 part of the code used by all Activity into an Activity class managed by 1 (all later named BaseActivity), and then this BaseActivity inherits from AppCompatActivity of Android system (1 is this). Inheritance: The Activity used on the page is inherited from our own BaseActivity, and the method encapsulated by BaseActivity is called directly within Activity.

3. Code and description

3.1. Advantages and disadvantages

Advantages: Reducing code repetition, improving code writing efficiency, and improving code maintainability Disadvantages: Do not put any code in BaseActivity, which may lead to BaseActivity too bloated, not conducive to code reading and maintenance, and even App collapse

The following will discuss which code should be placed in BaseActivity and which should be cautious

3.2. Code

Below I post a copy of my own encapsulated BaseActivity, which is explained in and below the code:


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());
        // Here is the initialization binding ButterKnife , in onDestory Destroyed it 
        mUnbinder = ButterKnife.bind(this);
        this.mActivity = this;
        // Unified 1 Will 1 A activity Add to 1 Inside a collection 
        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");
    }

    /**
     *  Display 1 A Fragment
     */
    public void showFragment(Fragment fragment) {
        if (fragment != null && fragment.isHidden()) {
            FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            fragmentTransaction.show(fragment);
            fragmentTransaction.commit();
        }
    }

    /**
     *  Hide 1 A Fragment
     */
    public void hideFragment(Fragment fragment) {
        if (fragment != null && !fragment.isHidden()) {
            FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            fragmentTransaction.hide(fragment);
            fragmentTransaction.commit();
        }
    }

	// This is 1 Settings toolbar Method for the title bar, ToolBarOptions Class mainly holds 1 Some 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();
                }
            });
        }
    }

	// Subclass direct call display toast
    public void showToast(String s) {
        ToastUtil.showToast(this, s);
    }

	// Provides a subclass 1 Acquisition activity Object 
    public Activity getActivity() {
        return this;
    }

	//1 A pop-up window loading Library  github Address: 
    //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(" Loading ...")
                .canceledOnTouchOutside(false)
                .cancelable(false)
                .show();
    }

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

	// This is exit app Related logic, you can do specific processing according to your own exit 
    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(" Prompt ")
                .content(" The account has been logged in elsewhere, please log out and log in again! ")
                .positiveText(" Determine ")
                .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();
    }

    // Begin contentLayout Front Adjust Layout ( Subclass can be copied separately if necessary )
    public void onAdjustLayout() {

    }

	// Here below 5 Methods are required to be implemented by subclasses, which are layout Layout, toolbar , mvp Adj. persenter Initialization, 
	//onCreate Inside initData And the page destroyed onDestroyActivity (Can be added according to your needs) 
    public abstract int setContentLayout();

    public abstract void initToolBar();

    public abstract void initPresenter();

    public abstract void initData(Bundle savedInstanceState);

    public abstract void onDestroyActivity();
}

3.3. Notices

There are log logs in each life cycle of BaseActivity. It is convenient to observe which life cycle is executed to activity. logcat can also be simply packaged under 1, and the system 1 controls whether the logs are printed. BaseActivity is not suitable for Activity of every page. For example, if you enter the splash screen page of the application, you can consider not inheriting BaseActivity, because this page usually does not need to write too much code. Or there are other special business scenarios. Attention should be paid to an Dialog pop-up problem. In BaseActivity, every time show1 has dialog, I create a new object, so I should pay attention to the fact that dialog can't go to show before it is closed, otherwise it may cause dialog to be abnormal. But don't hide the dialog pop-up window in the onDestory method, because when the A page enters the B page, it will first execute the onCreate, onStart and onResume methods in the life cycle of the B page, and then execute the onStop and onDestory methods of the A page, so it is wrong to destroy the A page after the B page is loaded. Sometimes, for convenience, someone may put the method of requesting permission detection in Android in BaseActivity, which is not particularly appropriate, because all pages inherited from BaseActivity will detect permission, which will lead to poor user experience. Therefore, it is recommended to request again where permission is used, and it is best to encapsulate a tool class by yourself, which is convenient to use. The encapsulation of BaseActivity does not require subclasses to implement activity lifecycle-related methods, except for a few abstract methods (I think subclasses need to be replicated, which can be determined according to their own business), and can be replicated by themselves if necessary.

4. Summary

It is not very complicated, and it is written in detail, which is basically applicable to most scenes. There may be other details that need attention.

The above is a detailed explanation of Android encapsulation of a global BaseActivity details, more information about Android encapsulation BaseActivity please pay attention to other related articles on this site!


Related articles: