<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Android MVP框架 詳細代碼

      android mvp的好處,網上一搜一大堆,相對于一開始普通的在activity中處理所有的不管是網絡請求還是頁面渲染,最大的好處是簡潔了,廢話不多說,看代碼

      這里網絡請求使用了兩種,一種是自己封裝的okhttp,一種是retrofit+rxjava,可以看出retrofit+rxjava的鏈式調用和普通的okhttp的區別

      mvp,m-model 處理數據,v-activity渲染展示,p-persenter 用于連接m和v,其中又引入鍥約類的概念,用于管理這三個所有的接口。

      先看代碼,

      ,為了方便我直接放在一個包里了,可以看到 有TestActivity,(mvp-v),TestModel(mvp-m),TestPersenter(mvp-p),其中TestContract就是契約類,用于管理用到的所有接口,多了一個TestCallback用于使用自己封裝的okhttp回調,使用retrofit+rxjava時可以省略,這其中也有人習慣把TestModel省略,直接在Persenter中處理數據然后在view中返回。

       

       

      先看契約類,其中BaseView可以提取一些公共的方法

       

      public interface TestContract {
      
          interface TestModel{
              void getData(String id,TestCallback callback);
              Observable<HomePage> getData();
          }
      
          interface TestPersenter{
              void getData(String id);
          }
          interface TestView extends BaseView {
      void SetData(HomePage homePage);
      }
       }
      public interface BaseView {
      
          void Toast(String s);
      
          /**
           * 綁定Android生命周期 防止RxJava內存泄漏
           *
           * @param <T>
           * @return
           */
          <T> AutoDisposeConverter<T> bindAutoDispose();
      
      }

       

      可以清楚的看到,model,persenter,view使用到的接口。

      再看activity中,implements  TestContract.TestView接口,必須實現接口中的方法----SetData,定義了一個按鈕,一個TextView,點擊按鈕,獲取數據,顯示在TextView中,其中TestPersenter testPersenter = new TestPersenter(this);體現了persenter的連接作用,獲取到實例,調用persenter中的getData方法,

      
      
      public class TestActivity extends BaseActivity implements TestContract.TestView {

      TestPersenter testPersenter = new TestPersenter(this);

      @BindView(R.id.button)
      Button button;
      @BindView(R.id.testview)
      TextView testview;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_test);
      ButterKnife.bind(this);

      button.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
      testPersenter.getData("1");
      }
      });
      }


      @Override
      public void SetData(HomePage homePage) {
      testview.setText(homePage.getMessage());
      }

      @Override
      public void Toast(String s) {
      super.Toast(s);

      }
      }
       
      public class BaseActivity extends AppCompatActivity implements BaseView {
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_base2);
              Window window = getWindow();
              window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
              getSupportActionBar().hide();
              ImmersionBar.with(this)
                      .statusBarColor(R.color.bar)     //狀態欄顏色,不寫默認透明色
                      .statusBarDarkFont(true) //原理:如果當前設備支持狀態欄字體變色,會設置狀態欄字體為黑色,如果當前設備不支持狀態欄字體變色,會使當前狀態欄加上透明度,否則不執行透明度
                      .fitsSystemWindows(true)
                      .keyboardEnable(true)
                      .init();
      
          }
      
          @Override
          protected void onDestroy() {
              super.onDestroy();
              // 必須調用該方法,防止內存泄漏
              ImmersionBar.destroy(this,null);
          }
          /**
           * 綁定生命周期 防止MVP內存泄漏
           *
           * @param <T>
           * @return
           */
          @Override
          public <T> AutoDisposeConverter<T> bindAutoDispose() {
              return AutoDispose.autoDisposable(AndroidLifecycleScopeProvider
                      .from(this, Lifecycle.Event.ON_DESTROY));
          }
      
          @Override
          public void Toast(String s) {
      
          }
      }

       

      TestPersenter,首先implements 接口,實現接口中的方法---getData,其次拿到了model和view,在getData方法中,調用model獲取數據,調用view的setData方法展示數據到頁面,從這里也可以看出persenter的連接作用,連接model和view。

      public class TestPersenter implements TestContract.TestPersenter{
      
          TestContract.TestModel model ;
          TestContract.TestView testView;
      
          public TestPersenter(TestContract.TestView testView) {
              this.testView = testView;
              this.model = new TestModel();
          }
      
          @Override
          public void getData(String id) {
              model.getData("1", new TestCallback() {
                  @Override
                  public <T> void success(T enty) {
                      testView.SetData((HomePage) enty);
                  }
      
                  @Override
                  public void error(String msg) {
                      
                  }
              });
          }
      }

      model:同樣implements接口,實現接口中的方法getData,第一個方法是使用自己封裝的okhttp網絡類,在這里就看出TestCallback 的作用了,訪問接口獲取數據后,通過TestCallback 返回,TestCallback 中只定義了兩個簡單的,一個成功時的回調,一個失敗時的回調

      
      
      public class TestModel implements TestContract.TestModel {

      @Override
      public void getData(String id, TestCallback callback) {
      new OkHttpUtil().getJson(HttpUrl.homePage, new OkHttpUtil.HttpCallBack() {
      @Override
      public void onSusscess(String data) throws JSONException, ParseException {
      HomePage homePage = new Gson().fromJson(data,HomePage.class);
      if(homePage.isSuccess()){
      callback.success(homePage);
      }else{
      callback.error(homePage.getMessage());
      }
      }

      @Override
      public void onError(String meg) {
      super.onError(meg);
      callback.error(meg);
      }
      });
      }

      @Override
      public Observable<HomePage> getData() {
             return RetrofitClient.getInstance().getApi().GetData();
          }
      }
       
      public interface TestCallback {
          <T> void success(T enty);
      
          void error(String msg);
      }

      使用retrofit+rxjava,可以看到,省略了TestCallback回調,直接鏈式調用,onNext中調用了view的setData方法顯示數據。

      public class TestPersenter implements TestContract.TestPersenter{
      
          TestContract.TestModel model ;
          TestContract.TestView testView;
      
          public TestPersenter(TestContract.TestView testView) {
              this.testView = testView;
              this.model = new TestModel();
          }
      
          @Override
          public void getData(String id) {
      //        model.getData("1", new TestCallback() {
      //            @Override
      //            public <T> void success(T enty) {
      //                testView.SetData((HomePage) enty);
      //            }
      //
      //            @Override
      //            public void error(String msg) {
      //
      //            }
      //        });
              
              model.getData()
                  .compose(RxScheduler.Obs_io_main())
                  .to(studyView.bindAutoDispose())
                  .subscribe(new Observer<HomePage>() {
                      @Override
                      public void onSubscribe(@NonNull Disposable d) {
      
                      }
      
                      @Override
                      public void onNext(@NonNull HomePage homePage) {
                          testView.SetData(homePage);
                      }
      
                      @Override
                      public void onError(@NonNull Throwable e) {
                 
      ) } @Override public void onComplete() { } }); } }



      retrofit的使用到的方法

       

       

       

      public interface APIService {

      /**
      * 首頁數據
      * @return
      */
      @GET("app/home_page/queryList")
      Observable<HomePage> GetData();

      }
      public class RetrofitClient {
      
          private static volatile RetrofitClient instance;
          private APIService apiService;
          private String baseUrl = "****";
          private Retrofit retrofit;
          private OkHttpClient okHttpClient;
      
          private RetrofitClient() {
          }
      
          public static RetrofitClient getInstance() {
              if (instance == null) {
                  synchronized (RetrofitClient.class) {
                      if (instance == null) {
                          instance = new RetrofitClient();
                      }
                  }
              }
              return instance;
          }
      
          /**
           * 設置Header
           *
           * @return
           */
          private Interceptor getHeaderInterceptor() {
              return new Interceptor() {
                  @Override
                  public Response intercept(@NonNull Chain chain) throws IOException {
                      Request original = chain.request();
                      Request.Builder requestBuilder = original.newBuilder();
                      //添加Token
      //                        .header("token", "");
                      Request request = requestBuilder.build();
                      return chain.proceed(request);
                  }
              };
      
          }
      
          /**
           * 設置攔截器 打印日志
           *
           * @return
           */
          private Interceptor getInterceptor() {
      
              HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
              //顯示日志
              interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
      
              return interceptor;
          }
      
          public OkHttpClient getOkHttpClient() {
              if (okHttpClient == null) {
                  //如果為DEBUG 就打印日志
                  if (BuildConfig.DEBUG) {
                      okHttpClient = new OkHttpClient().newBuilder()
                              //設置Header
                              .addInterceptor(getHeaderInterceptor())
                              //設置攔截器
                              .addInterceptor(getInterceptor())
                              .build();
                  } else {
                      okHttpClient = new OkHttpClient().newBuilder()
                              //設置Header
                              .addInterceptor(getHeaderInterceptor())
                              .build();
                  }
      
              }
      
              return okHttpClient;
          }
      
          public APIService getApi() {
              //初始化一個client,不然retrofit會自己默認添加一個
              if (retrofit == null) {
                  retrofit = new Retrofit.Builder()
                          //設置網絡請求的Url地址
                          .baseUrl(baseUrl)
                          //設置數據解析器
                          .addConverterFactory(GsonConverterFactory.create())
                          //設置網絡請求適配器,使其支持RxJava與RxAndroid
                          .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                          .client(getOkHttpClient())
                          .build();
              }
              //創建—— 網絡請求接口—— 實例
              if (apiService==null){
                  apiService = retrofit.create(APIService.class);
              }
      
              return apiService;
          }
      
      
      }

       

      public class RxScheduler {
      
          /**
           * 統一線程處理
           *
           * @param <T> 指定的泛型類型
           * @return FlowableTransformer
           */
          public static <T> FlowableTransformer< T, T> Flo_io_main() {
              return new FlowableTransformer<T, T>() {
                  @Override
                  public Publisher<T> apply(Flowable<T> upstream) {
                      return upstream.subscribeOn(Schedulers.io())
                              .observeOn(AndroidSchedulers.mainThread());
                  }
              };
          }
      
          /**
           * 統一線程處理
           *
           * @param <T> 指定的泛型類型
           * @return ObservableTransformer
           */
          public static <T> ObservableTransformer<T, T> Obs_io_main() {
              return new ObservableTransformer<T, T>() {
                  @Override
                  public ObservableSource<T> apply( Observable<T> upstream) {
                      return upstream.subscribeOn(Schedulers.io())
                              .observeOn(AndroidSchedulers.mainThread());
                  }
              };
          }
      
      }
      public interface BaseView {
      
          void Toast(String s);
      
          /**
           * 綁定Android生命周期 防止RxJava內存泄漏
           *
           * @param <T>
           * @return
           */
          <T> AutoDisposeConverter<T> bindAutoDispose();
      
      }
       //okhttp3
          implementation 'com.squareup.okhttp3:okhttp:4.2.0'
          implementation "com.squareup.okhttp3:logging-interceptor:3.10.0"
          implementation 'com.google.code.gson:gson:2.8.6'
      
          //retrofit2
          implementation 'com.squareup.retrofit2:retrofit:2.9.0'
          implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
          implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'
      
          //AutoDispose解決RxJava內存泄漏
          implementation 'com.uber.autodispose2:autodispose:2.0.0'
          implementation 'com.uber.autodispose2:autodispose-android:2.0.0'
          implementation 'com.uber.autodispose2:autodispose-lifecycle:2.0.0'
          implementation 'com.uber.autodispose2:autodispose-androidx-lifecycle:2.0.0'
        // 基礎依賴包,必須要依賴
      implementation 'com.gyf.immersionbar:immersionbar:3.0.0-beta07'
      // fragment快速實現(可選)
      implementation 'com.gyf.immersionbar:immersionbar-components:3.0.0-beta07'

       

      至此,mvp框架結束,mvp增加了接口,使頁面和數據處理分開,層次分明,后期好維護。在較小項目中,就幾個頁面,不必使用框架,也不必為了框架而使用,適合項目的才是最好的。

       

      posted @ 2021-12-09 10:00  頭一回  閱讀(1377)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产一区二区三区怡红院| 亚洲av无码精品色午夜| 国产成人不卡一区二区| 亚洲精品中文av在线| 欧洲精品码一区二区三区| 国产99久久无码精品| 日韩人妻一区中文字幕| 中文字幕一卡二卡三卡| 农村老熟女一区二区三区| 亚洲成人av在线高清| 国产女人喷潮视频免费| 厨房与子乱在线观看| 久久婷婷大香萑太香蕉AV人| 精品国产精品午夜福利| 人人爽亚洲aⅴ人人爽av人人片| 国产免费无遮挡吸奶头视频| 国产精品久久久久久福利| 亚洲永久精品免费在线看| 亚洲精品熟女一区二区| 菠萝菠萝蜜午夜视频在线播放观看 | 欧美视频二区欧美影视| 精品国产三级在线观看| 免费无码黄网站在线观看| 狠狠综合久久av一区二| 99久久久国产精品消防器材| 白嫩少妇无套内谢视频| 国产成人拍国产亚洲精品| 99精品国产兔费观看久久99| 国产激情文学亚洲区综合| 亚洲欧洲一区二区三区久久| 强奷乱码中文字幕| 乱女乱妇熟女熟妇综合网| 亚洲第一人伊伊人色综合| 久久国产精品日本波多野结衣| 亚洲AV成人片在线观看 | 亚洲一区av无码少妇电影| 久久热这里只有精品66| 国产一区二区三区黄网| 精品一卡2卡三卡4卡乱码精品视频| 偷拍美女厕所尿尿嘘嘘小便| 亚洲国产色婷婷久久99精品91|