从0到1手把手封装Android基类Activity/Fragment,告别重复代码,开发效率直接拉满!

从0到1手把手封装Android基类Activity/Fragment,告别重复代码,开发效率直接拉满!

哈喽各位同学,我是你们的技术博主~ 平时做Android开发的小伙伴,肯定都有过这样的崩溃瞬间:写每一个Activity、Fragment的时候,都要重复写布局绑定、控件初始化、数据加载、Toast提示、页面跳转、生命周期管理这些代码。

项目页面一多,重复代码堆成山,不仅写得累,后期维护更是噩梦------改一处共性逻辑,要翻遍所有页面挨个改,稍有遗漏就出bug。

其实解决这个问题的核心办法,就是封装通用基类BaseActivity和BaseFragment。把所有页面共有的逻辑、重复的方法全部抽离出来,子类只需要关注自身业务逻辑就行,代码简洁度和维护性直接提升一个档次。

今天这篇文章,就带大家从0到1完整封装一套实用的基类,全程干货无废话,代码可直接复制到项目中使用,新手也能轻松上手,建议收藏+转发,开发的时候随时翻看!


一、先搞懂:为什么必须封装基类?

在动手写代码之前,咱们先理清封装的核心意义,避免为了封装而封装,明白底层逻辑才能写好适配自己项目的基类。

1. 彻底消灭重复代码

常规开发中,每个Activity都要写setContentView、findViewById、initView、initData,Fragment还要处理视图创建、懒加载、内存泄漏问题,这些逻辑90%都是通用的,抽成基类后,子类不用再写一遍。

2. 统一管理页面逻辑

全局Toast样式、页面跳转规范、标题栏统一配置、权限申请、生命周期监听、异常捕获、加载框展示这些通用功能,在基类里写一次,所有子类自动生效,后期修改只动基类就行。

3. 降低代码耦合,提升可维护性

业务逻辑和通用逻辑彻底分离,子类只负责自身业务,代码结构更清晰,团队协作开发时,大家遵循同一套基类规范,不会出现五花八门的写法。

4. 规避常见开发坑点

比如Fragment懒加载、内存泄漏、视图空指针、重复加载数据等高频问题,在基类里提前做好处理,子类不用再单独踩坑。

博主温馨提示:基类封装遵循**"只抽共性,不掺业务"**原则,千万不要把业务代码写进基类,否则基类会越来越臃肿,失去封装的意义!

二、基础铺垫:核心概念快速过

针对刚接触Android开发的同学,快速过一遍基础概念,老鸟可以直接跳过这部分。

  • Activity:Android四大组件之一,是用户交互的界面载体,相当于一个独立的页面,负责展示UI、接收用户操作、管理生命周期。

  • Fragment:碎片,可以理解为"嵌入式子页面",必须依托Activity存在,能灵活组合、切换,常用于ViewPager、底部导航栏等场景,解决单Activity多页面的适配问题。

  • 基类封装核心 :利用抽象类+继承的特性,把通用逻辑写在抽象基类中,定义抽象方法强制子类实现业务相关逻辑。


三、第一步:封装BaseActivity,搭建页面核心基类

咱们先从Activity基类开始,这是整个项目页面的基础,适配主流的AndroidX开发,继承AppCompatActivity,兼容低版本系统。

1. 创建BaseActivity抽象类

首先新建一个抽象类BaseActivity,继承自AppCompatActivity,定义抽象方法强制子类实现,同时封装通用全局方法。

java 复制代码
import android.os.Bundle;
import android.view.LayoutInflater;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.widget.Toast;

/**
 * Activity通用基类
 * 抽象类,子类必须实现指定抽象方法
 */
public abstract class BaseActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 绑定布局
        setContentView(getLayoutId());
        // 初始化控件
        initView();
        // 初始化数据
        initData();
        // 初始化事件监听
        initListener();
    }

    /**
     * 子类实现,返回布局ID
     * @return 布局资源id
     */
    protected abstract int getLayoutId();

    /**
     * 初始化控件
     */
    protected abstract void initView();

    /**
     * 初始化数据
     */
    protected abstract void initData();

    /**
     * 初始化事件监听,非必需,子类可选择性重写
     */
    protected void initListener(){}

    // ==================== 通用工具方法封装 ====================
    /**
     * 全局Toast提示,避免重复Toast弹出
     */
    protected void showToast(String msg){
        if(msg != null && !msg.isEmpty()){
            Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 页面跳转,简化跳转代码
     */
    protected void skipActivity(Class<?> targetClass){
        startActivity(new Intent(this, targetClass));
    }

    /**
     * 带参数页面跳转
     */
    protected void skipActivity(Class<?> targetClass, Bundle bundle){
        Intent intent = new Intent(this, targetClass);
        if(bundle != null){
            intent.putExtras(bundle);
        }
        startActivity(intent);
    }
}

2. 基类核心逻辑解析

  • 抽象方法getLayoutId():强制子类返回自身布局文件ID,基类统一完成布局绑定,子类不用再写setContentView。

  • initView()、initData():抽象方法,子类负责控件初始化和数据加载,职责分离。

  • initListener():普通方法,非抽象,子类有需要才重写,避免强制实现无用方法。

  • 通用工具方法:Toast、页面跳转封装,子类直接调用,不用重复写代码。

3. 子类如何使用BaseActivity?

基类封装好之后,子类继承BaseActivity,只需要实现抽象方法,专注业务逻辑就行,代码量直接减少一半!

java 复制代码
public class MainActivity extends BaseActivity {

    @Override
    protected int getLayoutId() {
        // 直接返回自身布局
        return R.layout.activity_main;
    }

    @Override
    protected void initView() {
        // 初始化控件,比如findViewById、ViewBinding
    }

    @Override
    protected void initData() {
        // 加载网络数据、本地数据
        showToast("首页加载完成");
    }
}

是不是超级简洁?再也不用写重复的生命周期和初始化代码了!


四、第二步:封装BaseFragment,解决碎片痛点

Fragment的封装比Activity稍复杂,核心要解决懒加载、内存泄漏、视图重复创建这三大高频坑点,同样基于AndroidX封装,适配主流开发。

1. Fragment痛点分析

  • 默认创建就加载数据,多个Fragment切换时会重复加载,浪费性能和流量;

  • onCreateView多次调用,容易出现视图重复加载、空指针问题;

  • 控件引用不当,容易导致内存泄漏。

2. 完整BaseFragment封装代码

java 复制代码
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

/**
 * Fragment通用基类,实现懒加载,避免内存泄漏
 */
public abstract class BaseFragment extends Fragment {

    // 根视图,避免重复创建
    private View rootView;
    // 标记:视图是否创建完成
    private boolean isViewCreated = false;
    // 标记:是否已经加载过数据
    private boolean isDataLoaded = false;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        // 避免重复创建视图
        if(rootView == null){
            rootView = inflater.inflate(getLayoutId(), container, false);
        }
        isViewCreated = true;
        return rootView;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        initView(view);
        // 懒加载核心:视图创建完成后,判断是否可见,可见则加载数据
        lazyLoadData();
    }

    @Override
    public void onResume() {
        super.onResume();
        // 页面可见时,再次触发懒加载,适配切换后台返回场景
        lazyLoadData();
    }

    /**
     * 懒加载核心方法
     */
    private void lazyLoadData(){
        // 视图已创建、未加载过数据、当前Fragment可见
        if(isViewCreated && !isDataLoaded && isVisible()){
            initData();
            isDataLoaded = true;
        }
    }

    // ==================== 子类必须实现的抽象方法 ====================
    /**
     * 获取布局ID
     */
    protected abstract int getLayoutId();

    /**
     * 初始化控件
     */
    protected abstract void initView(View view);

    /**
     * 加载数据(懒加载触发)
     */
    protected abstract void initData();

    // ==================== 通用工具方法,复用Activity的逻辑 ====================
    protected void showToast(String msg){
        if(getActivity() != null && msg != null){
            ((BaseActivity) getActivity()).showToast(msg);
        }
    }

    /**
     * 销毁视图时,释放引用,避免内存泄漏
     */
    @Override
    public void onDestroyView() {
        super.onDestroyView();
        isViewCreated = false;
        isDataLoaded = false;
        rootView = null;
    }
}

3. 基类核心亮点解析

  • 视图复用:通过rootView缓存,避免onCreateView重复创建视图,解决重复渲染问题;

  • 懒加载实现:通过isViewCreated、isDataLoaded、isVisible()三个标记,只有Fragment对用户可见时,才会加载数据,大幅提升性能;

  • 内存泄漏防护:onDestroyView时清空视图引用,重置标记位,释放资源;

  • 方法复用:共用Activity的Toast方法,保持全局提示样式统一。

4. 子类使用BaseFragment示例

java 复制代码
public class HomeFragment extends BaseFragment {

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_home;
    }

    @Override
    protected void initView(View view) {
        // 初始化Fragment内的控件
    }

    @Override
    protected void initData() {
        // 懒加载数据,只有Fragment可见时才会执行
        showToast("首页Fragment懒加载完成");
    }
}

五、基类扩展:进阶功能补充(项目必备)

上面的基础版基类已经能满足日常开发,实际项目中,我们还可以扩展更多实用功能,直接加在基类里即可:

  • 统一标题栏管理:基类里封装通用标题栏,子类直接设置标题、左右按钮文案和点击事件;

  • 加载框/异常页封装:基类写showLoading()、hideLoading()、showErrorPage()方法,全局统一加载和异常样式;

  • 权限申请封装:基类封装权限检查、申请、结果回调方法,子类直接调用申请权限;

  • 生命周期监听:基类统一埋点、页面统计,不用每个子类都写;

  • ViewBinding适配:现在主流用ViewBinding替代findViewById,基类可以适配ViewBinding,进一步简化代码。

避坑提醒:扩展功能时,不要把所有功能都堆在一个基类里,业务复杂的项目,可以分多级基类,比如BaseMvpActivity、BaseVmActivity(ViewModel),分层更清晰。

六、总结:封装基类的核心思路

其实Android基类封装,核心就三步,不管是Activity还是Fragment,都遵循这个逻辑:

  1. 抽共性:把所有子类重复的逻辑、通用方法全部抽到基类;

  2. 定规范:用抽象方法定义子类必须实现的逻辑,固定代码结构;

  3. 防坑点:提前在基类处理生命周期、内存泄漏、性能问题,子类专注业务。

封装好一套通用基类,不仅能让开发效率提升50%以上,还能让项目代码变得整洁规范,后期维护、迭代、改bug都能省不少力气,不管是个人练手项目,还是公司商业项目,都是必备的基础优化。

相关推荐
小码哥_常1 小时前
Android 开发秘籍:用Tint为Icon动态变色
前端
ChoriaKiinweill1 小时前
不会有人现在还不了解BOM的知识吧? 关于它的一切都在这里!!!
前端
ChoriaKiinweill1 小时前
我们最爱操纵的DOM是个什么玩意? 关于DOM的知识快速一览!
前端
毛骗导演1 小时前
万字解析 OpenClaw 源码架构-代理系统(二)
前端·架构
im_AMBER1 小时前
从0到1实现块级编辑器的文件导入
前端·架构
不可能的是1 小时前
彻底搞懂 Module Federation(中中):MF 模块加载(上)
前端·webpack
毛骗导演1 小时前
万字解析 OpenClaw 源码架构-工具与自动化
前端
毛骗导演1 小时前
万字解析 OpenClaw 源码架构-代理系统(一)
前端·架构
波哥学开发1 小时前
🎯 Canvas 箭头绘制算法(附完整源码)
前端·计算机图形学