先来观察下这个base类:

先设置一泛型T,T为与presenter相关的view。BasePresenter中持有一个view的软引用。

在关联方法中将view对象传入,并存入软引用中,创建获取、取消关联和判断方法。

至于使用软引用,是为了防止所持的view都销毁了,但presenter一直持有,导致内存泄漏。

2、view的封装

view的封装,主要是BaseActivity和BaseFragment的封装。

2.1、BaseActivity

public abstract class BaseActivity<V, T extends BasePresenter> extends FragmentActivity {

public String TAG = getClass().getSimpleName() + “”;

protected T mPresenter;

public Context mContext;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

initActivityView(savedInstanceState);

mContext = BaseActivity.this;

//创建presenter
mPresenter = createPresenter();

// presenter与view绑定
if (null != mPresenter) {
mPresenter.attachView((V) this);
}

findViewById();

getData();

}

/**

  • 关于Activity的界面填充的抽象方法,需要子类必须实现
    */
    protected abstract void initActivityView(Bundle savedInstanceState);

/**

  • 加载页面元素
    */
    protected abstract void findViewById();

/**

  • 创建Presenter 对象
  • @return
    */
    protected abstract T createPresenter();

protected abstract void getData();

@Override
protected void onDestroy() {
super.onDestroy();

if (null != mPresenter) {
mPresenter.detachView();
}
}
}

BaseActivity设置两个泛型——V和P,明显地,分别代表对应的View和Presenter。

其持有一个BasePresenter,在onCreated方法中,使用createPresenter方法返回对应的BasePresenter的子类,我们就可以使用了。

这里注意一下view和presenter的处理:在onCreated中创建Presenter对象,但其内部的view软引用还是空;在onResume中关联view,此时presenter已经持有view的软引用;当然,还需要在onDestroy中取消关联。

至于其他的封装就不再介绍了,相信大家肯定还有更优的封装方法。

2.2 BaseFragment

public abstract class BaseFragment<V, T extends BasePresenter> extends Fragment {

public String TAG = getClass().getSimpleName() + “”;

private static final String STATE_SAVE_IS_HIDDEN = “STATE_SAVE_IS_HIDDEN”;
protected T mPresenter;

//定义一个View用来保存Fragment创建的时候使用打气筒工具进行的布局获取对象的存储
protected View view;

/**

  • 当Fragment进行创建的时候执行的方法
    */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

mPresenter = createPresenter();//创建presenter

}

@Override
public void onSaveInstanceState(Bundle outState) {
outState.putBoolean(STATE_SAVE_IS_HIDDEN, isHidden());
}

/**

  • 这个方法是关于Fragment完成创建的过程中,进行界面填充的方法,该方法返回的是一个view对象
  • 在这个对象中封装的就是Fragment对应的布局
    */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    view = initFragmentView(inflater);
    return view;
    }

/**

  • 这个方法当onCreateView方法中的view创建完成之后,执行
  • 在inflate完成view的创建之后,可以将对应view中的各个控件进行查找findViewById
    */
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
    initFragmentChildView(view);
    }

/**

  • 这个方法是在Fragment完成创建操作之后,进行数据填充操作的时候执行的方法
    */
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    initFragmentData(savedInstanceState);
    }

/**

  • 完成打气筒操作
    */
    protected abstract View initFragmentView(LayoutInflater inflater);

/**

  • 进行findViewById的操作
  • @param view 打气筒生成的View对象
    */
    protected abstract void initFragmentChildView(View view);

/**

  • 网络数据填充的操作
  • @param savedInstanceState
    */
    protected abstract void initFragmentData(Bundle savedInstanceState);

/**

  • 创建Presenter对象
    */
    protected abstract T createPresenter();

@Override
public void onResume() {
super.onResume();
if (null != mPresenter) {
mPresenter.attachView((V) this);
}
}

@Override
public void onDestroy() {
super.onDestroy();
if (null != mPresenter) {
mPresenter.detachView();
}
}

}

BaseFragment与BaseA类似就不再累赘。

3、Contract契约类

契约,顾名思义,规范定义,定义功能和模板。

在契约类中定义View的接口,Model的接口。因为Model将数据返给Presenter是使用回调方式,所以还需要再契约类中定义对应的回调。

具体看示例吧。

实战

这里我们以登录功能模块为例:

1、契约类

/**

  • Description:
  • Created by jia on 2017/12/20.
  • 人之所以能,是相信能
    */
    public class LoginContract {

public interface LoginView{

void onCheckFormatSuccess();

void onCheckFormatFail(String info);

void onLoginSuccess(Login login);

void onLoginFail(String errorInfo);
}

public interface LoginModel{
void login(String name,String password,LoginCallBack callBack);
}

public interface LoginCallBack{
void onSuccess(Login login);

void onFail(String errorInfo);
}
}

这里定义了登录页面的view接口、model接口和对应的回调。

在view中,只定义与UI展示的相关方法,如检查账号密码格式成功(失败)、登录成功(失败)等。

model负责数据请求,所以在接口中只定义了登录的方法。

回调定义了登录成功还是失败的方法。

2、Model实现类

/**

  • Description: 登录 Model实现类
  • Created by jia on 2017/12/20.
  • 人之所以能,是相信能

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

最后送福利了,现在关注我并且加入群聊可以获取包含源码解析,自定义View,动画实现,架构分享等。
内容难度适中,篇幅精炼,每天只需花上十几分钟阅读即可。
大家可以跟我一起探讨,欢迎加群探讨,有flutter—底层开发—性能优化—移动架构—资深UI工程师 —NDK相关专业人员和视频教学资料,还有更多面试题等你来拿

点击GitHub领取
录播视频图.png

330)]

最后送福利了,现在关注我并且加入群聊可以获取包含源码解析,自定义View,动画实现,架构分享等。
内容难度适中,篇幅精炼,每天只需花上十几分钟阅读即可。
大家可以跟我一起探讨,欢迎加群探讨,有flutter—底层开发—性能优化—移动架构—资深UI工程师 —NDK相关专业人员和视频教学资料,还有更多面试题等你来拿

点击GitHub领取
[外链图片转存中…(img-qpdhKciu-1710669624330)]

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐