The MVP mode + Retrofit2.0 framework encapsulation of kotlin & Java Android Development

Keywords: Java Retrofit Android network

Recently, I have been looking at Kotlin's Android code. By comparing Java, Kotlin is indeed a trend. Today, I will introduce how to integrate network requests into MVP mode. Some people may have a good understanding of some conceptual things, but the actual operation is another matter... This time, I will complete Kotlin code and Java code It is very suitable for Xiaobai to study.

About the introduction of MVP: m (Model) is the Model layer. Its function is to provide data, which corresponds to database, Beans, network requests, etc. in Andro. V (View) is the View layer. Its function is to provide the display of data. In Andro, it corresponds to activity, fragment, etc. P (Presenter) is the coordinator. The function is responsible for the realization of the main logic functions. M and V are linked, and m and V are completely separated.

Introduction to Retrofit2.0: Based on Okhttp, it's very good to use it.

1. First add the Retrofit dependency Library:

    //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. Preview the package structure (java and kotlin have the same package name)

3. Look at the JSON format of the data we requested, and then build the corresponding Bean

Code (note nested inside):

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. The usage of retrofit is mainly in NetPresenter and Service. Here is the key

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", "Server did not return successfully")
            } 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")) {
                        //According to the meaning of specific interface documents, for example, define - 1 as empty data
                        Log.e("main", "Definition-1 Null data")
                    }
                } else {
                    Log.e("main", "Server code error")
                }
            }


        }

        override fun onFailure(call: Call<ResponseInfo>?, t: Throwable?) {
            //No server connected
            Log.e("main", "No server connected")
        }
    }
}

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", "Server did not return successfully");
            }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 {
                        //According to the meaning of specific interface documents, for example, define - 1 as empty data
                        Log.e("main", "Definition-1 Null data");
                    }
                }
            }
        }

        @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=Self application")
    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=Self application")
    Call<ResponseInfo> getMainInfo();
}

5. The p layer code, the realization of main logic functions, and the view layer interact here.

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() {

    /**
     * Get data asynchronously
     */
    fun getMainInfo() {
        //Asynchronous access
        val homeCall = service.getMainInfo()
        homeCall.enqueue(callback)
    }

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

        //With data, success page, refresh UI
        if (datas.isNotEmpty()) {
            main.onMainSuccess(datas)
        } else {
            //No data, exception page
            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;
    }

    /**
     * Get data asynchronously
     */
    public void getMainInfo() {
        //Asynchronous access
        Call<ResponseInfo> homeCall = service.getMainInfo();
        homeCall.enqueue(callBack);

    }

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

        //With data, success page, refresh UI
        if (datas.size()>0){
            mMain.onMainSuccess(datas);
        }else {
            //No data, exception page
            mMain.onMainFailed();
        }
    }
}

6.V layer, data display. Here I use the log print data, which is not displayed on the app. It is abbreviated. In the actual development, the v-layer and P-layer call each other using a single instance or dagger to decouple.

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)//In the actual development, it can't be written in this way. Decoupling operation is needed
        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);//You can't write like this in actual development
        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. Finally, don't forget to add the permission to access the network

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

8. Operation results

Results of kotlin operation

Java run results

Finally, come on!

104 original articles published, 74 praised, 70000 visitors+
Private letter follow

Posted by alexweb on Sat, 11 Jan 2020 05:20:17 -0800