android MVP 实现查询手机号归属地

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dhl_1986/article/details/82956348

传统的MVC 在Android 实现

  1. Model  实体模型 和业务逻辑
  2. View 这里对应布局文件
  3. Controller 这里对应的是Activity 

MVC  在Android 上的实现,会让Activity 又像View 又像Controller ,代码变得越来越臃肿,越来越不可控。MVP 的出现解决了这个问题。

MVP 

  1. Model 依然是实体模型和业务逻辑
  2. View 这里对应 Activity  和布局文件
  3. Presenter 负责Model 和View 的交互

MVP 与MVC 的区别:

扫描二维码关注公众号,回复: 3531312 查看本文章

从图中可以看出 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;
  }



}

最终实现效果:

参考:

浅谈 MVP in Android

号码归属地查询实用工具

猜你喜欢

转载自blog.csdn.net/dhl_1986/article/details/82956348