• Android开发MVP架构记录


    Android开发MVP架构记录

    安卓的MVP(Model-View-Presenter)架构是一种常见的软件设计模式,用于帮助开发者组织和分离应用程序的不同组成部分。MVP架构的目标是将应用程序的业务逻辑(Presenter)、用户界面(View)和数据模型(Model)解耦,从而提高代码的可维护性、可测试性和可扩展性。

    下面是MVP架构中各个组成部分的角色和职责:

    1. Model(模型):Model表示应用程序的数据模型层,负责处理数据的获取、存储、操作以及业务逻辑的处理。它可以是数据库、网络请求、文件系统等。Model不直接与View交互,而是通过Presenter进行通信。

    2. View(视图):View是用户界面层,负责展示数据和接收用户的输入操作。它通常是Activity、Fragment或者自定义的View组件。View需要将用户的操作传递给Presenter,并将Presenter返回的数据展示给用户。

    3. Presenter(展示器):Presenter是连接Model和View的桥梁,负责处理业务逻辑和控制数据流。它接收用户的操作请求并根据需要从Model中获取数据,然后将处理结果传递给View进行展示。Presenter不直接操作View,而是通过定义的接口进行交互。

    MVP架构的优点包括:

    • 分离关注点:MVP架构将业务逻辑、数据模型和用户界面分离,使得各自的责任更加清晰,易于维护和修改。
    • 可测试性:由于Presenter和Model是独立的组件,并且没有直接依赖于Android Framework,因此可以更容易地进行单元测试。
    • 可扩展性:通过定义接口和契约类(Contract)来规范组件之间的交互,可以方便地进行功能扩展和替换。

    一个安卓项目结构示例:

    image-20230925185446075

    1. activity:存放activity页面

    2. adapter:存放适配器,配合RecycleView展示页面

    3. base:存放基类,如:BaseActivity、BaseFargment,将一些公共方法写在基类中

    4. entity:存放实体类,或一些数据结构对象

    5. essential:存放接口类,里面的接口定义了一系列规范,是程序的核心

      IView接口类:是(Activity或Fragment)视图的接口,定义视图有哪些执行方法,每个方法的具体实现中会对UI进行操作。

      //所有IView的接口
      public interface IView {
          //登录页接口规范
          interface LoginView extends BaseView{
              void successLogin();
              void failLogin();
          }
          //发现页接口规范
          interface ExploreView extends BaseView{
              void showBlogs(List<Blog> blogList);
          }
          //其他视图接口规范
      }
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

      IPrensenter接口类:是Prensenter的接口,定义了Presenter的行为

      //所有Presenter的接口
      public interface IPresenter {
          //登录presenter接口
          interface login extends BasePresenter {
              void checkLogin(String body);
          }
      	//发现prensenter接口
          interface exploreReq extends BasePresenter {
              void getPageBlogs(int page,int limit);
          }
          //其他presenter的接口
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
    6. fragment:存放fragment页面

    7. presenter:存放prensenter实现类

      image-20230925190614971

      public class ExplorePresenter implements IPresenter.exploreReq {
          IView.ExploreView exploreView;
      
          public ExplorePresenter(IView.ExploreView exploreView) {
              this.exploreView = exploreView;
          }
      
          @Override
          public BaseView getBase() {
              return exploreView;
          }
      
          //观察者
          Observer<List<Blog>> blogObserver = new Observer<List<Blog>>() {
              @Override
              public void onSubscribe(Disposable d) {
      
              }
      
              @Override
              public void onNext(List<Blog> blogList) {
                  exploreView.showBlogs(blogList);
              }
      
              @Override
              public void onError(Throwable e) {
      
              }
      
              @Override
              public void onComplete() {
      
              }
          };
      
          @Override
          public void getPageBlogs(int page, int limit) {
              ApiServiceFactory.getInstance().getPageBlogs(page, limit).subscribeOn(Schedulers.io())
                      .observeOn(AndroidSchedulers.mainThread())
                      .subscribe(blogObserver);
          }
      
      }
      
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
    8. retrofit:网络请求框架,存放相关类。

      image-20230925190803532

      ApiService类

      //retrofit定义接口
      public interface ApiService {
          @GET("api/getBlog/")
          Observable<List<Blog>> getPageBlogs(@Query("page") int page, @Query("limit") int limit);
          @POST("api/login")
          Observable<Result<User>> login(@Body String body);
          // 添加其他接口方法...
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

      ApiServiceFactory

      public class ApiServiceFactory {
          private static final String BASE_URL = "http://10.152.177.187:8180/";
          private static OkHttpClient okHttpClient;
          private static Retrofit retrofit;
          private static ApiService apiService;
          private static final long cacheSize = 1024 * 1024 * 15;// 缓存文件最大限制大小20M
          private static String cacheDirectory = Environment.getExternalStorageDirectory() + "/aop"; // 设置缓存文件路径
          private static Cache cache = new Cache(new File(cacheDirectory), cacheSize);  //
          public static ApiService getInstance() {
              if (apiService == null) {
                  if (retrofit == null) {
                      retrofit = createRetrofit();
                  }
                  apiService = retrofit.create(ApiService.class);
              }
              return apiService;
          }
      
          private static Retrofit createRetrofit() {
              return new Retrofit.Builder()
                      .baseUrl(BASE_URL)
                      .client(getOkHttpClient())
                      .addConverterFactory(GsonConverterFactory.create())
                      .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                      .build();
          }
      
          private static OkHttpClient getOkHttpClient() {
              if (okHttpClient == null) {
                  OkHttpClient.Builder builder = new OkHttpClient.Builder();
                  builder.connectTimeout(30, TimeUnit.SECONDS); // 设置连接超时时间
                  builder.writeTimeout(30, TimeUnit.SECONDS);// 设置写入超时时间
                  builder.readTimeout(30, TimeUnit.SECONDS);// 设置读取数据超时时间
                  builder.retryOnConnectionFailure(true);// 设置进行连接失败重试
      //            builder.addNetworkInterceptor(getInterceptor());
                  if (Constants.ISDEBUG) {
                      builder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));//拦截器
                  }
                  builder.cache(cache);// 设置缓存,cacheDir和cacheSize需要根据实际情况设置
                  okHttpClient = builder.build();
              }
              return okHttpClient;
          }
      
          private static Interceptor getInterceptor() {
              // 返回你自定义的拦截器,如果没有特殊需求可以返回null
              return null;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49

      Result类:规范返回数据结构类,使所有的返回数据结构为result类,真正数据存放在result.data中,这样就规范了返回结果。

      //统一返回数据结构
      public class Result<T> {
          private String code;
          private String msg;
          private T data; //T表示泛型
      
          public String getCode() {
              return code;
          }
      
          public String getMsg() {
              return msg;
          }
      
          public T getData() {
              return data;
          }
      
          public void setCode(String code) {
              this.code = code;
          }
      
          public void setMsg(String msg) {
              this.msg = msg;
          }
      
          public void setData(T data) {
              this.data = data;
          }
      
          public Result() {
          }
      
          public Result(T data) {
              this.data = data;
          }
      
          public static Result success() {
              Result result = new Result<>();
              result.setCode("200");
              result.setMsg("成功");
              return result;
          }
      
          public static <T> Result<T> success(T data) {
              Result<T> result = new Result<>(data);
              result.setCode("0");
              result.setMsg("成功");
              return result;
          }
      
          public static Result error(String code, String msg) {
              Result result = new Result();
              result.setCode(code);
              result.setMsg(msg);
              return result;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
    9. util:存放工具类、常量类、全局变量

  • 相关阅读:
    猿创征文|阿里云MaxCompute存取性能测试报告
    Docker通过Dockerfile创建Redis、Nginx--详细过程
    计算机毕业设计之儿童图书商城
    python知识点的一些归纳
    Java通过自定义类加载器模拟冰蝎免杀功能
    【电商】电商后台设计—库存模块
    栈和队列的那些“恩怨情仇”,被我抓个正着
    K8S(1)Pod
    ROS_TF
    springboot
  • 原文地址:https://blog.csdn.net/TGYAO/article/details/133278889