从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,都遵循这个逻辑:
-
抽共性:把所有子类重复的逻辑、通用方法全部抽到基类;
-
定规范:用抽象方法定义子类必须实现的逻辑,固定代码结构;
-
防坑点:提前在基类处理生命周期、内存泄漏、性能问题,子类专注业务。
封装好一套通用基类,不仅能让开发效率提升50%以上,还能让项目代码变得整洁规范,后期维护、迭代、改bug都能省不少力气,不管是个人练手项目,还是公司商业项目,都是必备的基础优化。