前几天发现,在Android项目代码里有一个Activity类行数居然有1000多行,而600行左右都是逻辑控制,真正和页面控件处理相关的代码不多,虽然可以用#region <>...#endregion块包起来,但是整体来说,页面和逻辑处理揉得太紧密了,有时代码复用起来也不方便,于是,决定重构,找了一下,有MVP(Model-View-Presenter,Model层负责数据管理,View层负责页面控件数据展示与设置,Presenter负责逻辑处理,控制View层如何显示与展示数据,这种层次设计,虽然代码文件多了,但是整体逻辑划分很清晰,对于团队分工和测试很方便)风格的架构还不错,了解了一下,不难,弄了半天,虽然多了几个代码文件和函数,但是原来那个Activity类行数缩减为400多行,逻辑看起来清爽多了。

  现在新建一个测试工程,来说明一下MVP是怎么使用的:

  1. 新建测试工程项目:

    

  2. 修改界面文件为如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="cn.linjk.testmvp.MainActivity"> <TextView
android:id="@+id/tv_info"
android:layout_gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textAlignment="center"/> <Button
android:id="@+id/btn_edit_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="Modify Info"/>
</LinearLayout>

      

  3. 增加界面修改接口:    

package cn.linjk.testmvp.views;

/**
* Created by LinJK on 24/12/2016.
*/ public interface IMainView {
String getTextViewInfo();
void setTextViewInfo(String info);
}

  4. 在MainActivity实现这个界面修改接口IMainView:

package cn.linjk.testmvp;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView; import cn.linjk.testmvp.views.IMainView; public class MainActivity extends AppCompatActivity
implements IMainView{ private TextView tvIninfo;
private Button btnModifyInfo; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initViewComponents();
} @Override
public String getTextViewInfo() {
return tvIninfo.getText().toString();
} @Override
public void setTextViewInfo(String info) {
tvIninfo.setText(info);
} private void initViewComponents() {
tvIninfo = (TextView) findViewById(R.id.tv_info);
btnModifyInfo = (Button) findViewById(R.id.btn_edit_info);
}
}

   5.增加MainActivity控制器接口IMainViewPresenter,用于控制界面的显示与内容设置逻辑:

package cn.linjk.testmvp.presenters;

/**
* Created by LinJK on 24/12/2016.
*/ public interface IMainViewPresenter {
void modifyTextViewInfo(String isssnfo);
}

   6.实现控制器接口:

package cn.linjk.testmvp.presenters;

import cn.linjk.testmvp.views.IMainView;

/**
* Created by LinJK on 24/12/2016.
*/ public class MainViewPresenter implements IMainViewPresenter{ private IMainView iMainView; public MainViewPresenter(IMainView pIMainView) {
this.iMainView = pIMainView;
} @Override
public void modifyTextViewInfo(String info) {
iMainView.setTextViewInfo(info);
}
}

   7. 在MainActivity增加控制器,增加控制逻辑,修改MainActivity后代码如下:

package cn.linjk.testmvp;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView; import cn.linjk.testmvp.presenters.MainViewPresenter;
import cn.linjk.testmvp.views.IMainView; public class MainActivity extends AppCompatActivity
implements IMainView{ private TextView tvIninfo;
private Button btnModifyInfo; private MainViewPresenter mainViewPresenter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initViewComponents();
initGlobalVars();
} @Override
public String getTextViewInfo() {
return tvIninfo.getText().toString();
} @Override
public void setTextViewInfo(String info) {
tvIninfo.setText(info);
} private void initViewComponents() {
tvIninfo = (TextView) findViewById(R.id.tv_info);
btnModifyInfo = (Button) findViewById(R.id.btn_edit_info);
btnModifyInfo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mainViewPresenter.modifyTextViewInfo("Android MVP");
}
});
} private void initGlobalVars() {
mainViewPresenter = new MainViewPresenter(this);
}
}

   8. 此时运行代码,完成目的。


   从上面代码逻辑可以看到,用这种方式编写代码,MainActivity类逻辑很清晰,不存在太多的逻辑控制代码,逻辑控制都在控制器处理了,这样在团队分工也容易分配,只要把业务接口写好了,就可以把接口分配人员去实现,当然,也有一个缺点是这样在项目复杂后很容易达到65535这个方法数限制,这样另外分DEX处理就行了。这种编程模式值得推荐使用。

Android开发之MVP模式的使用的更多相关文章

  1. Android开发之Buidler模式初探结合AlertDialog.Builder解说

          什么是Buidler模式呢?就是将一个复杂对象的构建与它的表示分离,使得相同的构建过程能够创建不同的表示.Builder模式是一步一步创建一个复杂的对象,它同意用户能够仅仅通过指定复杂对象 ...

  2. Android开发之Java集合类性能分析

    对于Android开发者来说深入了解Java的集合类很有必要主要是从Collection和Map接口衍生出来的,目前主要提供了List.Set和 Map这三大类的集合,今天Android吧(ard8. ...

  3. Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab

     今天我们要实现的这个效果呢,在Android的应用中十分地常见,我们可以看到下面两张图,无论是系统内置的联系人应用,还是AnyView的阅读器应用,我们总能找到这样的影子,当我们滑动屏幕时,Tab可 ...

  4. Android开发之Java必备基础

    Android开发之Java必备基础 Java类型系统 Java语言基础数据类型有两种:对象和基本类型(Primitives).Java通过强制使用静态类型来确保类型安全,要求每个变量在使用之前必须先 ...

  5. Android 开发之旅:深入分析布局文件&又是“Hello World!”

    http://www.cnblogs.com/skynet/archive/2010/05/20/1740277.html 引言 上篇可以说是一个分水岭,它标志着我们从Android应用程序理论进入实 ...

  6. android开发之Intent.setFlags()_让Android点击通知栏信息后返回正在运行的程序

    android开发之Intent.setFlags()_让Android点击通知栏信息后返回正在运行的程序     在应用里使用了后台服务,并且在通知栏推送了消息,希望点击这个消息回到activity ...

  7. Android开发之旅2:HelloWorld项目的目录结构

    引言 前面Android开发之旅:环境搭建及HelloWorld,我们介绍了如何搭建Android开发环境及简单地建立一个HelloWorld项目,本篇将通过HelloWorld项目来介绍Androi ...

  8. Android开发之MdiaPlayer详解

    Android开发之MdiaPlayer详解 MediaPlayer类可用于控制音频/视频文件或流的播放,我曾在<Android开发之基于Service的音乐播放器>一文中介绍过它的使用. ...

  9. android开发之 Wifi的四个类

    android开发之 Wifi的四个类 在Android中对Wifi操作,android本身提供了一些实用的包,在android.net.wifi包以下.简介一下: 大致能够分为四个基本的类ScanR ...

随机推荐

  1. JavaScript备忘录

    提取字符串substring(start,end)substr(start [, length ])JavaScript substr() 方法 --

  2. 【原】小玩node+express爬虫-1

    最近开始重新学习node.js,之前学的都忘了.所以准备重新学一下,那么,先从一个简单的爬虫开始吧. 什么是爬虫 百度百科的解释: 爬虫即网络爬虫,是一种自动获取网页内容的程序.是搜索引擎的重要组成部 ...

  3. Yii2.0 对的一些简单的操作

    1: 此方法返回 ['name' => 'daxia'] 的所有数据: User::find()->where(['name' => 'daxia'])->all(); 2: ...

  4. checkbox做全选按钮

    1.先写一个html页面,里面写一个全选按钮和几个复选框,实现下面2个要求 (1)点击全选按钮选中时,所有的复选框选中. (2)点击全选按钮取消选中时,所有复选框取消选中. <input typ ...

  5. 分享公司Entity与DTO之间数据拷贝的方法

    主题 最早以前自学java web的时候,数据库查询出来一个Entity对象(CMP对象).就直接传给前台展示了.并没有用到DTO对象,开始并没有觉得有什么不好...后来发现还是需要一些DTO对象来专 ...

  6. 【jQuery】初始化的三种方法

    JQ初始化方法实际上有两种,由于美元符号可以定义 jQuery,那么就有三种方法可以进行初始化操作,根据个人习惯来选择吧! 第一种 $(document).ready(function(){ // j ...

  7. 给Excel2013添加WebADI的Oracle加载项

    大家都知道,在Excel2013的加载项中是找不到WebADI的加载项的,EBS貌似有一个补丁,这里讲手动设置的步骤: 打开一个下载的WebADI的模板: 依次打开菜单: 文件>选项>自定 ...

  8. 2012Chhengdu K - Yet Another Multiple Problem

    K - Yet Another Multiple Problem Time Limit:20000MS     Memory Limit:65536KB     64bit IO Format:%I6 ...

  9. linux vi(vim)常用命令汇总

    1 查找 /xxx(?xxx) 表示在整篇文档中搜索匹配xxx的字符串, / 表示向下查找, ? 表示向上查找其中xxx可以是正规表达式,关于正规式就不多说了. 一般来说是区分大小写的, 要想不区分大 ...

  10. c#过滤html标签

    public string HtmlFilter(string html)     {         //设置要删除的标记         string[] lable = { "font ...