Android 的一个 MVP 基础项目模板

作者 : 开心源码 本文共5492个字,预计阅读时间需要14分钟 发布时间: 2022-05-12 共188人阅读

迄今为止,我阅读了很多有关Android软件开发中结构设计的文章。以我对他们的认识,比较好的方法是实现MVP(Model View Presenter)模式,这对Android开发者也是非常重要的。

我在其余开发者的技术博客和项目中学到了少量有用的东西,现在我决定开发一个基本的项目架构来用于实现我们的用户端软件mobiwise. 我选择了MVP模式作为项目架构,让我们开始理解一下。

什么是MVP?

你能在网上找到很多MVP相关解释和定义,让我来说一下我对MVP的了解。MVP是一种分离展现层和业务逻辑层的模式,使两者独立存在的模式。我相信分离这些部分的代码的过程属实令人厌烦。

为了这个实践,我们应该在项目中提供出各个笼统层。

为了使项目易于了解,我们首先做的是笼统出各个层面。这对开发测试和维护代码都非常重要。在任何Android项目中为了开发需要都会笼统出很多层,这里我说下重点!

项目中特有的业务逻辑部分,这里称之为Domain layer, 数据模型、网络相关、数据库操作部分,这里称之为Model layer,只有Android特有的部分,称之为Presentation or App Layer。 最后一个,也很重要,用于第三方library或者者项目中共用的、基础工具类等,称之 Common Layer.

我觉得,笼统出这么多层,在开始阶段,似乎难以了解和实现。

Domain Layer

这一层是完全独立的由于它指定了特定项目的业务逻辑。就我在网上查阅过的资料,这一层有个差不多的实现方式。根据项目的命名规则,定义出项目业务逻辑的用例接口,在创立出用例控制实现类来实现这个接口做相对应的工作。

让我们试想一个新闻应用程序,并试着定义个基本的业务用例场景。我定义了一个基本的业务用例接口,一个很简单的场景用例接口。

public interface GetPopularTitlesUsecase extends Usecase {  void getPopularTitles();  void onPopularTitlesReceived(ArrayList<Title> title);  void sendToPresenter();}

定义好接口,开始写class来实现GetPopularTitlesUsecase。下面是个基本的实现类。

public class GetPopularTitlesUsecaseController implements GetPopularTitlesUsecase {  private List<Title> titleList;  public GetPopularTitlesUsecaseController() {    BusUtils.getRestBusInstance().register(this);  }  @Override  public void getPopularTitles() {    SyncService.start();  }  @Subscribe  @Override  public void onPopularTitlesReceived(ArrayList<Title> titleList) {    this.titleList = titleList;    sendToPresenter();  }  @Override  public void sendToPresenter() {    BusUtils.getUIBusInstance().post(titleList);    BusUtils.getRestBusInstance().unregister(this);  }  @Override  public void execute() {    getPopularTitles();  }}

Model Layer

开发者都知道的,在项目中必需有一个Model Layer来解决网络请求和数据库存取相关的工作。我一般把这些部分的代码分成三个包,分别叫entity, rest和database。对于大部分项目分成这样已经足够。也许你需要创立有别于数据层的业务相关层。比方,你想展现客户的全称,就不应该通过在数据层中获取客户的姓和客户的名再通过指定的adapter类或者者view类等方式做一个拼接解决,这很笨拙,此时应该定义业务层来实现这个操作。定义两个不同的数据层很笨拙。但是依然重要。

Presentation or App Layer

这是最基本和熟知的笼统层,指代了Android程序开发中特有组件的部分。

View

View在MVP中代表UI组件部分。

public interface PopularTitlesView extends MVPView {  void showTitles(List<Title> titleList);  void showLoading();  void hideLoading();}

Presenter

Presenter在MVP中相似于连接view和model的桥梁。常用的实现方式,我们需要创立model接口来解决特定的场景。

public interface RadioListPresenter extends Presenter {  void loadRadioList();  void onRadioListLoaded(RadioWrapper radioWrapper);}

创立完简单的RadioListPresenter接口,我们来实现这个接口。

public class RadioListPresenterImp implements RadioListPresenter {  RadioListView radioListView;  GetRadioListUsecase getRadioListUsecase;  Bus uiBus;  @Inject  public RadioListPresenterImp(GetRadioListUsecase getRadioListUsecase, Bus uiBus) {    this.getRadioListUsecase = getRadioListUsecase;    this.uiBus = uiBus;  }  @Override  public void loadRadioList() {    radioListView.showLoading();    getRadioListUsecase.execute();  }  @Subscribe  @Override  public void onRadioListLoaded(RadioWrapper radioWrapper) {    radioListView.onListLoaded(radioWrapper);    radioListView.dismissLoading();  }  @Override  public void start() {    uiBus.register(this);  }  @Override  public void stop() {    uiBus.unregister(this);  }  @Override  public void attachView(MVPView mvpView) {    radioListView = (RadioListView) mvpView;  }}

所有以上这些来自我们代码中的例子,只是一个简单的实现。这些都不绝对完全也不是最好的,不同的项目需要不同的方式来实践,要视情况而定。

如何实践

每一个Activity,Fragment要根据逻辑功能来实现一个View接口,以我项目中的例子来说,RadioListFragment应该实现RadioListView接口,覆写相关的方法并让相关的presentar的方法来解决对应逻辑。

public class RadioListFragment extends Fragment implements RadioListView, SwipeRefreshLayout.OnRefreshListener {  @Inject  RadioListPresenter radioListPresenter;  public RadioListFragment() {  }  public static RadioListFragment newInstance() {    RadioListFragment fragment = new RadioListFragment();    return fragment;  }  @Override  public void onCreate(@Nullable Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    BusUtil.BUS.register(this);    initializeInjector();  }  @Override  public void onActivityCreated(@Nullable Bundle savedInstanceState) {    super.onActivityCreated(savedInstanceState);    radioListPresenter.loadRadioList();  }  private void initializeInjector() {    RadyolandApp app = (RadyolandApp) getActivity().getApplication();    DaggerGetRadioListComponent.builder()        .appComponent(app.getAppComponent())        .getRadioListModule(new GetRadioListModule())        .build()        .inject(this);  }  @Override  public View onCreateView(LayoutInflater inflater, ViewGroup container,                           Bundle savedInstanceState) {    View view = inflater.inflate(R.layout.fragment_radio_list, container, false);    ButterKnife.bind(this, view);    BusUtil.BUS.post(new TitleEvent(R.string.radio_list));    radioListPresenter.start();    radioListPresenter.attachView(this);    return view;  }  @Override  public void showLoading() {    swipeRefresh.setRefreshing(true);  }  @Override  public void dismissLoading() {    swipeRefresh.setRefreshing(false);  }  @Override  public void onListLoaded(RadioWrapper radioWrapper) {    radioListAdapter.setRadioList(radioWrapper.radioList);    radioListAdapter.notifyDataSetChanged();    DatabaseUtil.saveRadioList(radioWrapper.radioList);  }  @Subscribe  public void RefreshRadioListEvent(RefreshRadioListEvent radioListEvent) {    radioListPresenter.loadRadioList();  }  @Override  public void onDestroy() {    super.onDestroy();    BusUtil.BUS.unregister(this);  }  @Override  public void onRefresh() {    radioListPresenter.loadRadioList();  }

包组织结构的想法

当我第一次在网上搜索这方面的内容时,我发现很多开发者给每一层都分别创立了不同的modules。这个方法似乎适用于很多开发者,但是我不喜欢。是为什么我没有这么做的起因。我给每个module或者者层创立了不同的包,相信这不适用于所有人,只是我的方式,我感觉这样很舒服。

结论

我并不是想推荐给你在Android项目开发中使用的那些libraries,诸如Dagger 2, RxJava等。我只希望一切简单就好,把重点放在项目的结构设计上。

我相信MVP有很多的不同的实现方式,我经常会去学习其余开发者的方式,找出我认为最好的来实践。

重要的一点是我们应该开发一个可以独立于其余libraries、UI层、数据库和网络层的项目。假如你开发的项目基本满足以上,这个项目肯定是易于开发,测试和维护的。

最后

针对Android程序员,我这边给大家整理了少量资料,包括不限于高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!

  • Android前沿技术大纲

  • 全套体系化高级架构视频

资料领取:点赞+加群免费获取 Android IOC架构设计

加群 Android IOC架构设计领取获取往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、混合式开发(ReactNative+Weex)全方面的Android进阶实践技术,群内还有技术大牛一起探讨交流处理问题。

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Android 的一个 MVP 基础项目模板

发表回复