事物不会一成不变不断地学习与总结才会让我们在职场走的更远,相互学习相互鞭策生活会越来越好,希望我的分享能够帮助更多人。
1.添加依赖
//OkHttp3
implementation 'com.squareup.okhttp3:okhttp:3.2.0'
//日志拦截器
implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'
//Gson 库
implementation 'com.google.code.gson:gson:2.6.2'
//retrofit
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
//转换器,请求结果转换成Model
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
2.拦截器类
/**
* 添加公参
*/
public class HttpCommonInterceptor implements Interceptor {
private Map<String,String> mHeaderParamsMap = new HashMap<>();
public HttpCommonInterceptor() {
}
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Log.d("HttpCommonInterceptor","add common params");
Request oldRequest = chain.request();
// 新的请求
Request.Builder requestBuilder = oldRequest.newBuilder();
requestBuilder.method(oldRequest.method(),
oldRequest.body());
//添加公共参数,添加到header中
if(mHeaderParamsMap.size() > 0){
for(Map.Entry<String,String> params:mHeaderParamsMap.entrySet()){
requestBuilder.header(params.getKey(),params.getValue());
}
}
Request newRequest = requestBuilder.build(); return chain.proceed(newRequest);
}
public static class Builder{
HttpCommonInterceptor mHttpCommonInterceptor;
public Builder(){
mHttpCommonInterceptor = new HttpCommonInterceptor();
}
public Builder addHeaderParams(String key, String value){
mHttpCommonInterceptor.mHeaderParamsMap.put(key,value);
return this;
}
public Builder addHeaderParams(String key, int value){
return addHeaderParams(key, String.valueOf(value));
}
public Builder addHeaderParams(String key, float value){
return addHeaderParams(key, String.valueOf(value));
}
public Builder addHeaderParams(String key, long value){
return addHeaderParams(key, String.valueOf(value));
}
public Builder addHeaderParams(String key, double value){
return addHeaderParams(key, String.valueOf(value));
}
public HttpCommonInterceptor build(){
return mHttpCommonInterceptor;
}
}
}
3.HTTPS请求信任管理类
/**
* 解决异常javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
*/
public class HttpsTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
public static SSLSocketFactory createSSLSocketFactory() {
SSLSocketFactory sSLSocketFactory = null;
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new TrustManager[]{new HttpsTrustManager()},
new SecureRandom());
sSLSocketFactory = sc.getSocketFactory();
} catch (Exception e) {
}
return sSLSocketFactory;
}
public static class TrustAllHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
}
}
4.Retrofit工具类
public class RetrofitUtils {
private static final HttpService mServiceApi ;
public static HttpService getServiceApi() {
return mServiceApi;
}
static {
//请求头添加调用此方法
//HttpCommonInterceptor commonInterceptor = new HttpCommonInterceptor.Builder()
//.addHeaderParams("source", "android")
//.addHeaderParams("appVersion", "101")
//.build();
// 初始化OkHttpClient
OkHttpClient okHttpClient = new OkHttpClient.Builder()
//请求超时时间
.connectTimeout(20, TimeUnit.SECONDS)
//写入超时时间
.writeTimeout(20, TimeUnit.SECONDS)
//读取超时时间
.readTimeout(20, TimeUnit.SECONDS)
//安全HTTPS连接的套接字工厂和信任管理器
.sslSocketFactory(HttpsTrustManager.createSSLSocketFactory())
//用于主机名验证 验证服务器ca证书中的host是否和请求地址host一致
.hostnameVerifier(new HttpsTrustManager.TrustAllHostnameVerifier())
//添加请求头(公参)
//.addInterceptor(commonInterceptor)
.build();
Retrofit retrofit = new Retrofit.Builder()
// 访问后台接口的主路径
.baseUrl("http://v.juhe.cn/weather/")
// 添加解析转换工厂,Gson解析、Xml解析
.addConverterFactory(GsonConverterFactory.create())
// 添加OkHttpClient,不添加就是默认的光杆 OkHttpClient
.client(okHttpClient)
.build();
// 创建一个实例对象,静态代理模式
mServiceApi = retrofit.create(HttpService.class);
}
}
5.接口类
public interface HttpService {
@GET("index")
Call<DataBean> getOrideQuery(@QueryMap Map<String, String> parmas);
}
6.MVP
本来想把这一块单独摘出来的为了大家能够更好的看到实现效果就加到了一块,下边MVP写法是Google提出的一种MVP实现方式,通过Contract类统一管理Presenter和View的接口,Activity作为视图层来实现View并创建Presenter实例,Presenter分离Model与View作为中间者进行数据的传递,Model主要做数据的请求与存储
Contract
public class WeatherContract {
public interface View{
void WeatherQuerySuccess(WeatherData weatherData);
void WeatherQueryFailure(String string);
}
public interface Presenter{
void WeatherQuerySuccess(WeatherData weatherData);
void WeatherQueryFailure(String string);
}
}
Model
public class HttpServerUtils {
/**
* 天气查询
*
* @param presenter
*/
public static void WeatherPortal(final WeatherContract.Presenter presenter, HashMap map) {
Call<WeatherData> call = RetrofitUtils.getServiceApi().getweatherQuery(map);
call.enqueue(new Callback<WeatherData>() {
@Override
public void onResponse(Call<WeatherData> call, Response<WeatherData> response) {
if (response.body() != null){
presenter.WeatherQuerySuccess(response.body());
}
}
@Override
public void onFailure(Call<WeatherData> call, Throwable t) {
presenter.WeatherQueryFailure(t.toString());
}
});
}
}
这里我们对我们的Presenter进行一下封装主要是用来存储/删除已经创建好的Presenter实例;如果不需要的话可自行去除 AbstractPresenter/Presenter/ WrapperPresenter 三个类
Presenter
public abstract class AbstractPresenter {
/**
* 外层presenter 下包裹的所有presenter的集合
*
* @return presenter的集合
*/
abstract Map<String, AbstractPresenter> getPresentsMap();
/**
* 根据具体 的类型获取对应的实例
*
* @param presenterClass presenter类型
* @param <T> 限制获取实例类型
* @return 返回对应类型的实例
*/
public synchronized <T extends Presenter> T getPresenter(Class<T> presenterClass) {
T presenter = (T) getPresentsMap().get(presenterClass.getName());
return presenter;
}
}
***
public class Presenter extends AbstractPresenter{
WrapperPresenter mWrapperPresenter;
/**
* 将外层的包裹 引用给被包裹的presenter,目的是获取外层包裹的presenter集合
*
* @param wrapperPresenter
*/
public void initWrapperPresenter(WrapperPresenter wrapperPresenter) {
mWrapperPresenter = wrapperPresenter;
}
public WrapperPresenter getWrapperPresenter() {
return this.mWrapperPresenter;
}
@Override
Map<String, AbstractPresenter> getPresentsMap() {
return getWrapperPresenter() != null ? getWrapperPresenter().getPresentsMap() : null;
}
public void onDestroy(){
}
}
***
public class WrapperPresenter extends AbstractPresenter {
private static volatile WrapperPresenter mWrapperPresenter = null;
/**
* 存放所有Presenter}
*/
private Map<String, AbstractPresenter> mMap = new HashMap<>();
private WrapperPresenter(){
}
public static WrapperPresenter getInstance(){
if (mWrapperPresenter == null){
synchronized (WrapperPresenter.class){
if (mWrapperPresenter == null){
mWrapperPresenter = new WrapperPresenter();
}
}
}
return mWrapperPresenter;
}
@Override
Map<String, AbstractPresenter> getPresentsMap() {
return mMap;
}
/**
* { Presenter}添加到包裹WrapperPresenter中,持有各个presenter引用便于presenter之间通信
*
* @param presenters 需要添加到WrapperPresenter中的所有子的Presenter集合
*/
public void add(Presenter... presenters) {
if (presenters == null || presenters.length == 0) {
return;
}
for (Presenter presenter : presenters) {
mMap.put(presenter.getClass().getName(), presenter);
presenter.initWrapperPresenter(this);
}
}
public void removeAll(){
Presenter p = null;
for (AbstractPresenter presenter:mMap.values()){
((Presenter)presenter).onDestroy();
presenter = null;
}
mMap.clear();
mWrapperPresenter = null;
}
public void remove(Class presenterClass){
mMap.remove(presenterClass.getName());
}
}
***
public class WeatherPresenter extends Presenter implements WeatherContract.Presenter{
private final Context mContext;
private final WeatherContract.View mView;
public WeatherPresenter(WeatherContract.View view, Context context) {
this.mContext = context;
this.mView = view;
}
public void getWeatherData(HashMap map) {
HttpServerUtils.WeatherPortal(this,map);
}
@Override
public void WeatherQuerySuccess(WeatherData weatherData) {
mView.WeatherQuerySuccess(weatherData);
}
@Override
public void WeatherQueryFailure(String string) {
mView.WeatherQueryFailure(string);
}
}
View
public class MainActivity extends AppCompatActivity implements WeatherContract.View,View.OnClickListener{
private WeatherPresenter weatherPresenter;
private EditText inputCityEdit;
private TextView weatherMessageText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initPresenter();
}
public void initView(){
//获取控件
inputCityEdit = findViewById(R.id.input_city_et);
Button queryButton = findViewById(R.id.query_bt);
queryButton.setOnClickListener(this);
weatherMessageText = findViewById(R.id.weather_message_tv);
}
public void initPresenter(){
//如果为空则创建Presenter实例并保存实例
if (weatherPresenter == null){
weatherPresenter = new WeatherPresenter(this, this);
WrapperPresenter.getInstance().add(weatherPresenter);
}
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.query_bt:
if (inputCityEdit.getText().toString().length() == 0 || TextUtils.isEmpty(inputCityEdit.getText())){
Toast.makeText(this, "城市名不能为空!", Toast.LENGTH_SHORT).show();
}else {
//聚合数据 接口请求次数有限
HashMap<String, String> map = new HashMap<>();
map.put("cityname",inputCityEdit.getText().toString());
map.put("key","7763f3e73a13f244bd6c7337660fd8bd");
weatherPresenter.getWeatherData(map);
}
break;
}
}
@Override
public void WeatherQuerySuccess(WeatherData weatherData) {
WeatherData.ResultBean result = weatherData.getResult();
WeatherData.ResultBean.TodayBean today = result.getToday();
Log.d("cwf", "WeatherQuerySuccess:"+weatherData.getResultcode());
weatherMessageText.setText("城市:"+today.getCity()+"\n"+
"\n"+"日期:"+today.getDate_y()+"\n"+
"\n"+"温度:"+today.getTemperature()+"\n"+
"\n"+"风向:"+today.getWind()+"\n"+
"\n"+"穿着:"+today.getDressing_advice()+"\n");
}
@Override
public void WeatherQueryFailure(String string) {
Log.d("cwf", "WeatherQueryFailure: "+string);
}
}