MVP从MVC演变而来,通过表示器将视图与模型巧妙地分开。在该模式中,视图通常由表示器初始化,它呈现用户界面(UI)并接受用户所发出命令,但不对用户的输入作任何逻辑处理,而仅仅是将用户输入转发给表示器。通常每一个视图对应一个表示器,但是也可能一个拥有较复杂业务逻辑的视图会对应多个表示器,每个表示器完成该视图的一部分业务处理工作,降低了单个表示器的复杂程度,一个表示器也能被多个有着相同业务需求的视图复用,增加单个表示器的复用度。表示器包含大多数表示逻辑,用以处理视图,与模型交互以获取或更新数据等。模型描述了系统的处理逻辑,模型对于表示器和视图一无所知。
[1]
MVP的全称为Model-View-Presenter,Model提供数据,View负责显示,Controller/Presenter负责逻辑的处理。MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter(MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过Controller。
[2]
本书适合于有一定Java编程基础的读者。如果读者已熟练掌握Java编程语法并具有一定图形界面编程经验,阅读本书将十分合适。否则,阅读本书之前建议先认真阅读疯狂Java体系之《疯狂Java讲义》。
自定义view:
在Java平台中, 清单文件(Manifest file)是JAR档案中包含的特殊文件。Manifest文件被用来定义扩展或档案打包相关数据,是一个元数据文件,它包含了不同部分中的名/值对数据。如果一个JAR文件被用来作为可执行文件,那么其中的Manifest文件需要指出该程序的主类文件。通常Manifest文件的文件名为MANIFEST.MF。
清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:name=".app.App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
1) Java 开发中有两个大名鼎鼎的项目构建 ANT、Maven。
2) Google 推荐使用的 Android studio 是采用 Gradle 来构建项目。Gradle 是一个非常先进的项目构建工具。
Gradle 是用了一种基于 Groovy 的领域特定语言(DSL,Demain Specific Language)来声明项目设置,摒弃了 XML(如 ANT 和 Maven)的各种繁琐配置。
3) 项目中一般会出现2个或者多个 build.gradle 文件,一个在根目录下,一个在 app 目录下。
如果切换到 Android 模式下则全部在 Gradle Scripts。
依赖
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.1"
defaultConfig {
minSdkVersion 15
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
//解析依赖
implementation 'com.google.code.gson:gson:2.8.5'
//volley请求框架
implementation 'com.android.volley:volley:1.1.1'
代码如下:
mvp契约
public interface IproductContract {
interface IModel{
void getProducts(String url,IModelCallBack iModelCallBack);
interface IModelCallBack{
void success(ProductEntity productEntity);
void error(Throwable throwable);
}
}
interface IView{
void success(ProductEntity productEntity);
void error(Throwable throwable);
}
interface IPresenter{
void getProducts(String url);
}
}
mvp m层
public class ProductModel implements IproductContract.IModel {
@Override
public void getProducts(String url, final IModelCallBack iModelCallBack) {
VolleyUtils.getInstance().doGet(url, new VolleyUtils.VolleyCallBack() {
@Override
public void success(String response) {
final ProductEntity productEntity = new Gson().fromJson(response, ProductEntity.class);
iModelCallBack.success(productEntity);
}
@Override
public void error(Throwable throwable) {
iModelCallBack.error(throwable);
}
});
}
}
mvp P层
public class ProdutPressenter implements IproductContract.IPresenter {
private IproductContract.IView iView;
private ProductModel model;
public ProdutPressenter(IproductContract.IView iView) {
this.iView = iView;
model=new ProductModel();
}
@Override
public void getProduct(String url) {
model.getProduct(url, new IproductContract.IModel.ModelCallBack() {
@Override
public void success(ProductEntity productEntity) {
iView.success(productEntity);
}
@Override
public void error(Throwable throwable) {
iView.error(throwable);
}
});
}
}
VolleyUtils类
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
public class VolleyUtils {
private RequestQueue queue;
private static VolleyUtils volleyUtils;
public static VolleyUtils getInstance() {
if (volleyUtils==null){
synchronized ((VolleyUtils.class)){
if (volleyUtils==null){
volleyUtils = new VolleyUtils();
}
}
}
return volleyUtils;
}
private VolleyUtils(){
queue= Volley.newRequestQueue(App.getContext());
}
public void doGet(String url, final VolleyCallBack volleyCallBack){
final StringRequest stringRequest = new StringRequest(StringRequest.Method.GET, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (volleyCallBack!=null){
volleyCallBack.success(response);
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (volleyCallBack!=null){
volleyCallBack.error(error);
}
}