版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dhl_1986/article/details/82956348
传统的MVC 在Android 实现
- Model 实体模型 和业务逻辑
- View 这里对应布局文件
- Controller 这里对应的是Activity
MVC 在Android 上的实现,会让Activity 又像View 又像Controller ,代码变得越来越臃肿,越来越不可控。MVP 的出现解决了这个问题。
MVP
- Model 依然是实体模型和业务逻辑
- View 这里对应 Activity 和布局文件
- Presenter 负责Model 和View 的交互
MVP 与MVC 的区别:
从图中可以看出 MVC 中Model 可以和View 交互的,而MVP中 Model 和View 不能交互,他们是通过Presenter 交互的。
查询手机是归属地 demo 实现:
引用两个库:
implementation 'com.squareup.okhttp3:okhttp:3.11.0'
implementation 'com.google.code.gson:gson:2.8.5'
权限,基本的网络请求需要网络权限:
<uses-permission android:name="android.permission.INTERNET"/>
先贴上封装的HttpUtils:
public class HttpUtils {
String mUrl ;
Map<String ,String> mParam;
HttpResponse mHttpResponse;
Handler UIHandler = null;
OkHttpClient okHttpClient = null;
Gson gson = null;
private static HttpUtils mInstance ;
/**
* 初始化一些基本数据
*/
private HttpUtils()
{
okHttpClient = new OkHttpClient();
gson = new Gson();
UIHandler = new Handler(Looper.getMainLooper());
}
public static HttpUtils getInstance()
{
if(mInstance == null)
{
synchronized(HttpUtils.class)
{
if(mInstance == null)
{
mInstance = new HttpUtils();
}
}
}
return mInstance ;
}
/**
* 回调接口
*/
public interface HttpResponse
{
void onSuccess(Object object);
void onFail(String object);
}
public void sendPostHttp(String url ,Map<String,String> param)
{
sendHttp(url,param,true);
}
public void sendGetHttp(String url ,Map<String,String> param,HttpResponse httpResponse)
{
mHttpResponse = httpResponse ;
sendHttp(url,param,false);
}
public void sendHttp(String url,Map<String,String> param,boolean isPost)
{
mUrl = url ;
mParam = param;
//请求逻辑
run(isPost);
}
private void run(boolean isPost)
{
Request request = createRequest(isPost);
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
if(mHttpResponse != null)
{
UIHandler.post(new Runnable() {
@Override
public void run() {
mHttpResponse.onFail("请求错误");
}
});
}
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
if(mHttpResponse == null)
return ;
UIHandler.post(new Runnable() {
@Override
public void run() {
try {
String json = response.body().string();
int index = json.indexOf("{");
json = json.substring(index);
Phone phone = gson.fromJson(json,Phone.class);
mHttpResponse.onSuccess(phone);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
});
}
private Request createRequest(boolean isPost)
{
Request request = null;
if(isPost)
{
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
//遍历Map
Iterator<Map.Entry<String,String>> iterator = mParam.entrySet().iterator();
while(iterator.hasNext())
{
Map.Entry<String,String> entry = iterator.next();
builder.addFormDataPart(entry.getKey(),entry.getValue());
request = new Request.Builder().url(mUrl).post(builder.build()).build();
}
}else
{
String urlStr = mUrl +"?"+MapParamToString(mParam);
request = new Request.Builder().url(urlStr).build();
}
return request ;
}
private String MapParamToString(Map<String,String> mParam)
{
StringBuilder stringBuilder = new StringBuilder();
Iterator<Map.Entry<String,String>> iterator = mParam.entrySet().iterator();
while(iterator.hasNext())
{
Map.Entry<String,String> entry = iterator.next();
stringBuilder.append(entry.getKey()+"="+entry.getValue()+"&");
}
String str = stringBuilder.toString().substring(0,stringBuilder.length());
return str ;
}
}
Model 编写:这里的model 就是查询手机归属的Phone 类:
public class Phone {
String telString;
String province;
String carrier;
String catName;
public String getTelString() {
return telString;
}
public void setTelString(String telString) {
this.telString = telString;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCarrier() {
return carrier;
}
public void setCarrier(String carrier) {
this.carrier = carrier;
}
public String getCatName() {
return catName;
}
public void setCatName(String catName) {
this.catName = catName;
}
}
View 这里写贴上布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="手机号查询"
android:layout_gravity="center"
android:layout_marginTop="20dp"
/>
<EditText
android:id="@+id/edit_query"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_margin="20dp"
android:hint="请输入手机号码"
/>
<Button
android:id="@+id/button_query"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询"
android:layout_gravity="center"
android:layout_margin="20dp"
/>
<TextView
android:id="@+id/result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询结果"
android:layout_gravity="center"
android:layout_margin="20dp"
/>
</LinearLayout>
Presenter 是通过接口与View 交互的,这里要实现两个接口:
/**
* 基本Loading 接口
*/
public interface MvpLoadingView {
void showLoading();
void hidenLoading();
}
/**
* 更新UI接口
*/
public interface MvpMainView extends MvpLoadingView{
void showToast(String msg);
void updateView(Object object);
}
View 最后实现的部分 ,就是Activity 了:
public class MainActivity extends AppCompatActivity implements MvpMainView {
EditText edit_query ;
TextView button_query,result ;
MainPresenter mainPresenter ;
private ProgressDialog progressDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initId();
initEvent();
mainPresenter = new MainPresenter(this);
mainPresenter.attach(this);
}
private void initId()
{
edit_query = findViewById(R.id.edit_query);
button_query = findViewById(R.id.button_query);
result = findViewById(R.id.result);
}
private void initEvent()
{
button_query.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String phone = edit_query.getText().toString();
mainPresenter.searchPhoneInfo(phone);
}
});
edit_query.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
if(editable.toString().length()>=11)
{
String phone = edit_query.getText().toString();
mainPresenter.searchPhoneInfo(phone);
}
}
});
}
@Override
public void showToast(String msg) {
}
@Override
public void updateView(Object object) {
Phone phone = (Phone)object;
result.setText("手机号码:"+phone.getTelString()+"\n"+"省份:"+phone.getProvince());
}
@Override
public void showLoading() {
progressDialog = new ProgressDialog(this);;
progressDialog.setMessage("loading");
progressDialog.show();
}
@Override
public void hidenLoading() {
progressDialog.dismiss();
}
}
剩下来就是Presenter 的编写了:
/**
* 基本 Presenter
*/
public class BasePresenter {
Context mContext ;
public void attach(Context context)
{
mContext = context;
}
public void onPause(){}
public void onResume(){}
public void onDestroy(){}
}
/**
* 查询手机归属 presenter
*/
public class MainPresenter extends BasePresenter{
public static final String url = "https://tcc.taobao.com//cc/json/mobile_tel_segment.htm";
MvpMainView mvpMainView ;
public Phone getmPhone() {
return mPhone;
}
Phone mPhone ;
public MainPresenter(MvpMainView mainView)
{
mvpMainView = mainView ;
}
public void searchPhoneInfo(String phone)
{
if(phone.length() !=11)
{
mvpMainView.showToast("请输入正确的手机号码");
return ;
}
mvpMainView.showLoading();
sendHttp(phone);
}
private void sendHttp(String phone)
{
Map<String,String > map = new HashMap<>();
map.put("tel",phone);
HttpUtils.getInstance().sendGetHttp(url, map, new HttpUtils.HttpResponse() {
@Override
public void onSuccess(Object object) {
mvpMainView.hidenLoading();
mvpMainView.updateView(object);
}
@Override
public void onFail(String object) {
mvpMainView.showToast(object);
mvpMainView.hidenLoading();
}
});
//httpUtils.sendGetHttp(url,map);
}
private Phone parsePhone(String json)
{
Phone phone = new Phone();
try {
JSONObject jsonObject = new JSONObject(json);
String value = jsonObject.getString("telString");
phone.setTelString(value);
value = jsonObject.getString("province");
phone.setProvince(value);
value = jsonObject.getString("catName");
phone.setCatName(value);
value = jsonObject.getString("carrier");
phone.setCarrier(value);
} catch (JSONException e) {
e.printStackTrace();
}
return phone;
}
private Phone parseWithGson(String json)
{
Gson gson = new Gson();
Phone phone = gson.fromJson(json,Phone.class);
return phone;
}
}
最终实现效果:
参考: