iis服务器助手广告
返回顶部
首页 > 资讯 > 移动开发 >详解Android封装一个全局的BaseActivity
  • 145
分享到

详解Android封装一个全局的BaseActivity

2024-04-02 19:04:59 145人浏览 泡泡鱼
摘要

1.前言 对于一个Android开发者来说,每一个页面都继承一个单独的系统Activity,有时候会带来很多不必要的困扰。比如:每一个页面会有重复的代码,阅读起来麻烦;每

1.前言

  • 对于一个Android开发者来说,每一个页面都继承一个单独的系统Activity,有时候会带来很多不必要的困扰。比如:每一个页面会有重复的代码,阅读起来麻烦;每一次写新的页面功能总要打开原来的页面代码拷贝一部分过来;有时候代码调试排查问题也不方便等等。
  • 如果你的项目里面没有将Activity都继承自一个自己封装的BaseActivity、或者针对自己封装的BaseActivity觉得还不够完善的,这篇博客可能会对你有帮助!

2.特点

  • 封装:将所有Activity都用到的一部分代码封装到一个统一管理的Activity类(后面全部起名叫BaseActivity),然后由这个BaseActivity继承自Android系统的AppCompatActivity(一般是这个)。
  • 继承:页面上用到的Activity都继承自我们的自己BaseActivity,BaseActivity封装的方法在Activity内直接调用。

3.代码及说明

3.1.优缺点

  • 优点:减少了代码的重复,提高了写代码的效率、以及提高了代码的维护性
  • 缺点:不要任何代码都放在BaseActivity,那样可能会导致BaseActivity过于臃肿,不利于代码的阅读和维护,甚至出现App奔溃

下面会讨论哪些代码应该放在BaseActivity里面,哪些需要谨慎

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;
        //统一将一个activity添加到一个集合里面
        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");
    }

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

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

	//这是一个设置toolbar标题栏的方法,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();
                }
            });
        }
    }

	//子类直接调用展示toast
    public void showToast(String s) {
        ToastUtil.showToast(this, s);
    }

	//给子类提供一个获取activity对象的方式
    public Activity getActivity() {
        return this;
    }

	//一个弹窗loading库 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相关的逻辑,可以根据自己的退出做具体的处理
    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("账号已在其他地方登录,请退出重新登录!")
                .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前调整布局(子类若有需要可以单独复写)
    public void onAdjustLayout() {

    }

	//下面这5个方法是子类必须实现的,分别是layout布局、toolbar、mvp的persenter初始化、
	//onCreate内的initData、以及页面销毁的onDestroyActivity(可以根据自己的需要添加)
    public abstract int setContentLayout();

    public abstract void initToolBar();

    public abstract void initPresenter();

    public abstract void initData(Bundle savedInstanceState);

    public abstract void onDestroyActivity();
}

3.3.注意点

  • 在BaseActivity的每个生命周期内都有log日志,这里是方便观察执行到activity的哪个生命周期,loGCat也可以简单封装一下,统一控制日志是否打印。
  • BaseActivity并不适合每一个页面的Activity,比如进入应用的闪屏页面,就可以考虑不继承BaseActivity,因为这个页面通常不需要写太多代码。或者还有其他特殊的业务场景下。
  • 需要注意一个Dialog弹窗问题,在BaseActivity里面,每次show一个dialog的时候我都是创建一个新的对象,那么就要注意dialog在未关闭之前不能再去show,否则可能会导致dialog出现异常。但是不要在onDestory方法里面去隐藏dialog弹窗,因为在A页面进入B页面的时候,会先执行到B页面生命周期的onCreate、onStart、onResume三个方法,然后再执行A页面的onStop可能还有onDestory方法,所以等B页面加载完成再去销毁A页面是错误的。
  • 有时候为了方便可能有人会把请求Android中权限检测的方法放在BaseActivity里面,这样并不是特别合适,因为所有继承自BaseActivity的页面都会去检测权限,这样会导致用户体验差,所以建议用到权限的地方再去请求,最好自己封装一个工具类,用起来方便一点。
  • BaseActivity的封装并不强求子类必须实现activity生命周期相关的方法,除了几个抽象方法(我认为子类需要复写的,可以根据业务自己定),必要的话可以自己复写。

4.总结

不是很复杂,写的也比较详细,也基本适用于绝大部分的场景。可能还有其他需要注意的细节回头想起来再补上。

以上就是详解Android封装一个全局的BaseActivity的详细内容,更多关于Android封装BaseActivity的资料请关注编程网其它相关文章!

--结束END--

本文标题: 详解Android封装一个全局的BaseActivity

本文链接: https://www.lsjlt.com/news/123239.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 详解Android封装一个全局的BaseActivity
    1.前言 对于一个Android开发者来说,每一个页面都继承一个单独的系统Activity,有时候会带来很多不必要的困扰。比如:每一个页面会有重复的代码,阅读起来麻烦;每...
    99+
    2024-04-02
  • Android简单封装一个MVP基类流程详解
    目录ModelPresenterViewExample对于MVP架构我想大家都不陌生吧,对于现在的主流框架非MVP + RxJava + Retrofit莫属了,GitHub上也有很...
    99+
    2023-03-12
    Android封装MVP Android封装MVP基类
  • vue封装一个弹幕组件详解
    目录前言功能实现1、获取随机颜色随机数生成随机颜色编码生成2、随机生成弹幕出现的高度坐标3、格式化弹幕对象颜色定位4、创建弹幕对象滚动动画定义创建弹幕dom对象实例弹幕销毁弹幕循环5...
    99+
    2022-11-13
    vue封装弹幕组件 vue封装组件
  • Vue中怎么封装一个自动化注册全局组件
    这篇文章主要介绍“Vue中怎么封装一个自动化注册全局组件”,在日常操作中,相信很多人在Vue中怎么封装一个自动化注册全局组件问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Vue中怎么封装一个自动化注册全局组件...
    99+
    2023-06-25
  • JavaScript实现封装一个快速生成目录树的全局脚本
    目录说在前面思路分析功能实现一、使用命令行交互来获取所需参数二、编写目录文件树生成逻辑三、封装成全局插件四、插件安装使用源码地址说在前面 我们在很多地方都可以看到有这样的目录树结构...
    99+
    2023-03-15
    JavaScript生成目录树 JavaScript目录树
  • Android startActivityForResult的调用与封装详解
    目录前言一、原生的使用二、对原生的封装Ghost三、Result Api 的使用四、Result Api 的封装4.1 封装简化创建方式4.2 自动注册/按需注册总结前言 start...
    99+
    2023-03-23
    Android startActivityForResult调用 Android startActivityForResult封装 Android startActivityForResult
  • react封装全局弹框的方法
    本文实例为大家分享了react封装全局弹框的具体代码,供大家参考,具体内容如下 弹框效果图 文件布局 index.js import React, { Component ...
    99+
    2024-04-02
  • 怎么封装一个vue中也可使用的uniapp全局弹窗组件
    这篇文章主要介绍了怎么封装一个vue中也可使用的uniapp全局弹窗组件的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么封装一个vue中也可使用的uniapp全局弹窗组件文章都会有所收获,下面我们一起来看看吧...
    99+
    2023-07-05
  • Android从实现到封装一个MVP的示例
    这篇文章主要介绍了Android从实现到封装一个MVP的示例,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。前言MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方...
    99+
    2023-05-30
    android mvp
  • 利用Android封装一个有趣的Loading组件
    目录前言组件定义圆形Loading椭圆运动Loading贝塞尔曲线Loading组件使用总结前言 在上一篇普通的加载千篇一律,有趣的 loading 万里挑一 中,我们介绍了使用Pa...
    99+
    2022-11-13
    Android封装Loading组件 Android Loading组件 Android Loading
  • 封装一个更易用的Dialog组件过程详解
    目录场景搭建环境创建组件创建调用组件的hook函数Dialog的缓存、隐藏隐藏缓存完整代码总结场景 在项目中,我们经常会遇到使用弹窗的场景,但有时组件库自带的弹窗不能满足我们的需求,...
    99+
    2024-04-02
  • JavaScript如何实现封装一个快速生成目录树的全局脚本
    本篇内容主要讲解“JavaScript如何实现封装一个快速生成目录树的全局脚本”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript如何实现封装一个快速生成目录树的全局脚本”吧!说在...
    99+
    2023-07-05
  • Android如何简单封装一个MVP基类
    这篇文章主要介绍“Android如何简单封装一个MVP基类”,在日常操作中,相信很多人在Android如何简单封装一个MVP基类问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Android如何简单封装一个MV...
    99+
    2023-07-05
  • Vue封装全局toast组件的应用
    这篇文章主要介绍“Vue封装全局toast组件的应用”,在日常操作中,相信很多人在Vue封装全局toast组件的应用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Vue封装全局toast组件的应用”的疑惑有所...
    99+
    2023-06-20
  • Android全局获取Context实例详解
    Android全局获取Context实例详解在弹出Toast 启动活动 发送广播 操作数据库 使用通知等等时都需要Context如果操作在活动中进行是很简单的,因为活动本身就是一个Context对象但是当逻辑代码脱离了Activity类,此...
    99+
    2023-05-31
    android context roi
  • Android 全局异常捕获实例详解
    Android 全局异常捕获今天就来说说作为程序猿的我们每天都会遇到的东西bug,出bug不可怕可怕的是没有出bug时的堆栈信息,那么对于bug的信息收集就显得尤为重要了,一般用第三方bugly或者友盟等等都能轻易收集,但是由于公司不让使用...
    99+
    2023-05-31
    android 全局 异常捕获
  • Android SharedPreferences存取操作以及封装详解
    存 首先初始化 private SP sp; sp = new SP( context ); 存入数据 第一个参数为上下文,第二个参数为key,第三个参数为要存入的数据Val...
    99+
    2024-04-02
  • Vue封装全局toast组件的完整实例
    目录前言 一. 借助 vue-cli 1. 定义 Toast 组件2. 在 main.js 里面配置3. 在其他组件内使用二、不借助 vue-cli 1. 注册 toast 组件2....
    99+
    2024-04-02
  • 一文详解websocket在vue2中的封装使用
    目录websocket在vue2中的封装使用实现思路:步骤页面中使用方式在vue中的封装websocket在vue2中的封装使用 先说需求: 页面中有websocket连接,进入的...
    99+
    2023-03-08
    vue2封装websocket vue2 websocket
  • jquery中Ajax全局调用封装的示例分析
    小编给大家分享一下jquery中Ajax全局调用封装的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!前言:有一种情况:全...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作