Kotlin&Java-Android开发之MVP模式+Retrofit2.0框架封装

前言:最近一直再看Kotlin的安卓代码,通过对比Java,Kotlin确实是一个趋势,好了今天我介绍一下如何把网络请求融入到MVP模式之中,可能有的人对一些概念性的东西理解起来很好,可是实际操作起来,却又是另外一回事......,这次我会把Kotlin代码和Java代码都完整的放出来,非常适合小白学习。


关于MVP的介绍:M(Model)即模型层,功能是提供数据,放在安卓中对应的是数据库、Beans、网络请求等。V(View)即视图层,功能是提供数据的展示,放在安卓中对应的是activity、fragment等。P(Presenter)即协调者,功能是负责主要逻辑功能的实现,将M和V进行联系起来,M和V彻底分离。

关于Retrofit2.0的介绍:基于Okhttp,总之很牛X,用就行了。


1.首先添加Retrofit依赖库:

    //retrofit2.0
    implementation 'com.squareup.retrofit2:retrofit:2.1.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
    implementation 'com.google.code.gson:gson:2.2.4'

2.预览一下包的结构(java和kotlin的包名一样)

3.看下我们请求的数据JSON格式,然后建立起相对应的Bean

代码(注意里面嵌套的):

ResponseInfo.kt

package com.fly.retrofitdemo.model.beans

data class ResponseInfo (
    var error_code: String,
    var reason: String,
    var result: Result
)

data class Result(
    var stat: String,
    var data: List<Data>
)
data class Data(
    var author_name: String,
    var category: String,
    var date: String,
    var thumbnail_pic_s: String,
    var title: String,
    var uniquekey: String,
    var url: String
)
ResponseInfo.java
package com.fly.retrofitjavademo.model.beans;

import java.util.List;

public class ResponseInfo {
    public String error_code;
    public String reason;
    public Result result;

    public class Result{
        public String stat;
        public List<Data> data;

        public class Data{
            public String author_name;
            public String category;
            public String date;
            public String thumbnail_pic_s;
            public String title;
            public String uniquekey;
            public String url;
        }
    }

}

4.Retrofit的用法主要是在NetPresenter和Service里,这里是关键

NetPresenter.kt

package com.fly.retrofitdemo.model.net

import android.util.Log
import com.fly.retrofitdemo.model.beans.Data
import com.fly.retrofitdemo.model.beans.ResponseInfo
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

open abstract class NetPresenter {
    val service: Service
    val url = "http://v.juhe.cn/toutiao/"
    init {
        val retrofit = Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create())
                .build()

        service = retrofit.create<Service>(Service::class.java!!)
    }

    abstract fun transmitDatas(datas: List<Data>)

    val callback = object : Callback<ResponseInfo> {
        override fun onResponse(call: Call<ResponseInfo>?, response: Response<ResponseInfo>?) {
            if (response == null) {
                Log.e("main", "服务器没有成功返回")
            } else {
                if (response.isSuccessful()) {
                    val responseInfo = response.body()
                    if (responseInfo.error_code.equals("0")) {

                        val json = responseInfo.result
                        val datas:List<Data> = json.data
                        transmitDatas(datas)

                    } else if (responseInfo.error_code.equals("-1")) {
                        //根据具体接口文档表示含义,比如定义-1为空数据
                        Log.e("main", "定义-1为空数据")
                    }
                } else {
                    Log.e("main", "服务器代码错误")
                }
            }


        }

        override fun onFailure(call: Call<ResponseInfo>?, t: Throwable?) {
            //没有连上服务器
            Log.e("main", "没有连上服务器")
        }
    }
}

NetPresenter.java

package com.fly.retrofitjavademo.model.net;

import android.util.Log;

import com.fly.retrofitjavademo.model.beans.ResponseInfo;

import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

abstract public class NetPresenter {
    public Service service;
    private String url = "http://v.juhe.cn/toutiao/";

    public NetPresenter(){
        Retrofit  retrofit = new Retrofit.Builder().baseUrl(url).addConverterFactory(GsonConverterFactory.create()).build();
        service = retrofit.create(Service.class);
    }

    abstract public void transmitDatas(List<ResponseInfo.Result.Data> datas);

    public Callback<ResponseInfo> callBack = new Callback<ResponseInfo>(){

        @Override
        public void onResponse(Call<ResponseInfo> call, Response<ResponseInfo> response) {
            if (response == null) {
                Log.e("main", "服务器没有成功返回");
            }else {
                if (response.isSuccessful()){
                    ResponseInfo responseInfo = response.body();
                    if (responseInfo.error_code.equals("0")){
                        ResponseInfo.Result result = responseInfo.result;
                        List<ResponseInfo.Result.Data> datas =  result.data;
                        transmitDatas(datas);
                    }else {
                        //根据具体接口文档表示含义,比如定义-1为空数据
                        Log.e("main", "定义-1为空数据");
                    }
                }
            }
        }

        @Override
        public void onFailure(Call<ResponseInfo> call, Throwable t) {

        }
    };
}

Service.kt

package com.fly.retrofitdemo.model.net

import com.fly.retrofitdemo.model.beans.ResponseInfo
import retrofit2.Call
import retrofit2.http.GET

interface Service {

    @GET("index?type=caijing&key=自己申请")
    fun getMainInfo(): Call<ResponseInfo>
}

Service.java

package com.fly.retrofitjavademo.model.net;

import com.fly.retrofitjavademo.model.beans.ResponseInfo;

import retrofit2.Call;
import retrofit2.http.GET;

public interface Service {
    @GET("index?type=caijing&key=自己申请")
    Call<ResponseInfo> getMainInfo();
}

5.P层代码,主要逻辑功能的实现,这里和view层进行交互。

MainPresenter.kt
package com.fly.retrofitdemo.presenter

import com.fly.retrofitdemo.model.beans.Data
import com.fly.retrofitdemo.model.net.NetPresenter
import com.fly.retrofitdemo.ui.MainActivity

class MainPresenter(val main: MainActivity) : NetPresenter() {

    /**
     * 使用异步获取数据
     */
    fun getMainInfo() {
        //异步访问
        val homeCall = service.getMainInfo()
        homeCall.enqueue(callback)
    }

    override fun transmitDatas(datas: List<Data>) {

        //有数据,成功页面,刷新UI
        if (datas.isNotEmpty()) {
            main.onMainSuccess(datas)
        } else {
            //无数据,异常页面
            main.onMainFailed()
        }
    }
}



MainPresenter.java
package com.fly.retrofitjavademo.presenter;

import com.fly.retrofitjavademo.model.beans.ResponseInfo;
import com.fly.retrofitjavademo.model.net.NetPresenter;
import com.fly.retrofitjavademo.ui.MainActivity;

import java.util.List;

import retrofit2.Call;

public class MainPresenter extends NetPresenter {
    private MainActivity mMain;

    public MainPresenter(MainActivity mainActivity){
        mMain = mainActivity;
    }

    /**
     * 使用异步获取数据
     */
    public void getMainInfo() {
        //异步访问
        Call<ResponseInfo> homeCall = service.getMainInfo();
        homeCall.enqueue(callBack);

    }

    @Override
    public void transmitDatas(List<ResponseInfo.Result.Data> datas) {

        //有数据,成功页面,刷新UI
        if (datas.size()>0){
            mMain.onMainSuccess(datas);
        }else {
            //无数据,异常页面
            mMain.onMainFailed();
        }
    }
}

6.V层,数据的显示,这里我是使用的是日志打印数据,没有在app上显示。里面进行了简写,实际开发中V层和P层相互调用是要使用单例或者dagger来进行解耦的。

MainActivity.kt
package com.fly.retrofitdemo.ui

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.fly.retrofitdemo.model.beans.Data
import com.fly.retrofitdemo.presenter.MainPresenter
import com.fly.retrofitdemo.R


class MainActivity : AppCompatActivity() {

    lateinit var presenter: MainPresenter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        presenter = MainPresenter(this)//实际开发中不能这样写,要进行解耦操作
        presenter.getMainInfo()
    }

    fun onMainSuccess(datas: List<Data>) {
        for (data in datas){
            Log.e("---",data.title)
        }
    }

    fun onMainFailed() {

    }
}
MainActivity.java
package com.fly.retrofitjavademo.ui;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;

import com.fly.retrofitjavademo.R;
import com.fly.retrofitjavademo.model.beans.ResponseInfo;
import com.fly.retrofitjavademo.presenter.MainPresenter;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private MainPresenter presenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        presenter = new MainPresenter(this);//实际开发中不能这样写
        presenter.getMainInfo();
    }

    public void onMainSuccess(List<ResponseInfo.Result.Data> datas) {
        for (int i = 0;i<datas.size();i++){
            Log.e("---",datas.get(i).title);
        }
    }

    public void onMainFailed() {
    }
}

7.最后不要忘记加上访问网络的权限

<uses-permission android:name="android.permission.INTERNET"/>

8.运行结果

kotlin运行结果

Java运行结果


最后说一句话,各位加油!

发布了105 篇原创文章 · 获赞 74 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/qq_32306361/article/details/103939890