前言:最近一直再看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 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;
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::class.java!!)
}
abstract fun transmitDatas(datas: List)
val callback = object : Callback {
override fun onResponse(call: Call?, response: Response?) {
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 = 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?, 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 datas);
public Callback callBack = new Callback(){
@Override
public void onResponse(Call call, Response 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 datas = result.data;
transmitDatas(datas);
}else {
//根据具体接口文档表示含义,比如定义-1为空数据
Log.e("main", "定义-1为空数据");
}
}
}
}
@Override
public void onFailure(Call 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
}
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 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) {
//有数据,成功页面,刷新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 homeCall = service.getMainInfo();
homeCall.enqueue(callBack);
}
@Override
public void transmitDatas(List 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) {
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 datas) {
for (int i = 0;i
7.最后不要忘记加上访问网络的权限
8.运行结果
kotlin运行结果
Java运行结果
最后说一句话,各位加油!