Android——自定义拦截器实现OKHttp网络请求

示例图:


一、技术选型:

1. 项目框架:MVP;注意:避免内存泄漏;

2. 图片加载: Universal-Image-Loader或Glide图片加载框架

3.网络加载框架:OkHttp

4. 自定义应用拦截器,封装公共请求参数(注意:必须通过拦截器封装公共请求参数,否则无法请求数据)

公共请求参数,在我们项目研发过程中,作用非常大。封装公共请求承参数之后,那么所有的接口都会默认携带这些公共参数,达到复用的效果。

公共请求参数:source=android

参数名称:source

参数值:android

类型:String

是否必传:是

5. 数据展示使用RecylerView;

二、业务逻辑需求:

1. 搜索框输入关键字(笔记本、手机),其他关键词没有数据,点击搜索实现如图效果;

2. 图1是列表布局,图2是网格布局;

3. 通过右上角按钮点击切换列表布局和网格布局,按钮随着切换;

4. 实现下拉刷新展示第一页数据、上拉加载更多实现分页功能。

三、接口:

http://120.27.23.105/product/searchProducts

keywords=笔记本&page=1

参数说明:

keywords 关键字字段 String类型 必传

page  页码数  String类型  必传

公共参数:source 来源字段 String类型 (通过自定义拦截器封装)

MainActivity.java

package com.bawei.com.wangruixin1509c20171113;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;

import com.bawei.com.wangruixin1509c20171113.adapter.NewsListAdapter;
import com.bawei.com.wangruixin1509c20171113.bean.JavaBean;
import com.bawei.com.wangruixin1509c20171113.httputils.INewsView;
import com.bawei.com.wangruixin1509c20171113.presenter.NewsPresenter;
import com.jwenfeng.library.pulltorefresh.BaseRefreshListener;
import com.jwenfeng.library.pulltorefresh.PullToRefreshLayout;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements INewsView{

    private RecyclerView re_view;
    private List<JavaBean.DataBean> list;
    private NewsListAdapter adapter;
    private Button btn_sousuo;
    private EditText et_sousuo;
    private NewsPresenter presenter;
    private ImageView right;
    private boolean flag = true;
    private PullToRefreshLayout mpull;
    private int page = 1;
    private String show;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        re_view = (RecyclerView) findViewById(R.id.re_view);
        btn_sousuo = (Button) findViewById(R.id.btn_sousuo);
        et_sousuo = (EditText) findViewById(R.id.et_sousuo);
        right = (ImageView) findViewById(R.id.right);
        mpull = (PullToRefreshLayout) findViewById(R.id.mpull);

        list = new ArrayList<>();
        adapter = new NewsListAdapter(this, list,1);
        LinearLayoutManager manager = new LinearLayoutManager(this);
        re_view.setLayoutManager(manager);
        re_view.setAdapter(adapter);
        presenter = new NewsPresenter();
        presenter.attachView(this);


        btn_sousuo.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                show = et_sousuo.getText().toString().trim();
                presenter.getNews(show,page);

            }
        });
        right.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                if (flag){
                    adapter.notifyDataSetChanged();
                        adapter = new NewsListAdapter(MainActivity.this, list,2);
                        right.setImageDrawable(getResources().getDrawable(R.mipmap.lv_icon));
                        GridLayoutManager manager = new GridLayoutManager(MainActivity.this, 2);
                        re_view.setLayoutManager(manager);
                        re_view.setAdapter(adapter);
                        flag = false;
                }else {
                    adapter.notifyDataSetChanged();
                    adapter = new NewsListAdapter(MainActivity.this, list,1);
                    right.setImageDrawable(getResources().getDrawable(R.mipmap.grid_icon));
                    LinearLayoutManager manager = new LinearLayoutManager(MainActivity.this);
                    re_view.setLayoutManager(manager);
                    re_view.setAdapter(adapter);
                    flag = true;
                }
                return false;
            }
        });
        mpull.setLayoutMode(MODE_APPEND);//设置模板
        mpull.setRefreshListener(new BaseRefreshListener() {
            @Override
            public void refresh() {
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        page=1;
                        presenter.getNews(show,page);
                        mpull.finishRefresh();

                    }
                }, 3000);

            }

            @Override
            public void loadMore() {
                new Handler().postDelayed(new Runnable() {
                                              @Override
                                              public void run() {
                                                  page++;
                                                  presenter.getNews(show,page);
                                                  mpull.finishLoadMore();

                                              }
                                          }, 3000

                );

            }
        });
    }

    @Override
    public void success(String tag, List<JavaBean.DataBean> news) {
        list.clear();
        list.addAll(news);
        adapter.notifyDataSetChanged();
        adapter.setOnItemClickListener(new NewsListAdapter.OnItemClickListener() {
            @Override
            public void onClick(int position) {
                Intent intent = new Intent(MainActivity.this, Main2Activity.class);
                String url = list.get(position).getDetailUrl();
                intent.putExtra("url",url);
                startActivity(intent);
            }

            @Override
            public void onLongClick(int position) {

            }
        });
    }

    @Override
    public void failed(String tag, Exception e) {

    }
}
HttpUtils-get请求

package com.bawei.com.wangruixin1509c20171113.httputils;

import android.os.Handler;
import android.text.TextUtils;

import com.bawei.com.wangruixin1509c20171113.callback.CallBack;
import com.bawei.com.wangruixin1509c20171113.utils.GsonUtils;

import java.io.IOException;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * Created by Wangrx on 2017/11/13.
 */

public class HttpUtils {
    private static Handler handler = new Handler();
    private static volatile HttpUtils instance;
    private HttpUtils(){

    }
    public static HttpUtils getInstance(){
        if (null==instance){
            synchronized (HttpUtils.class){
                if (instance == null){
                    instance = new HttpUtils();
                }
            }
        }
        return instance;
    }
    public void get(String url, Map<String,String> map, final CallBack callBack, final Class cls, final String tag){
        if (TextUtils.isEmpty(url)){
            return;
        }
        StringBuffer sb = new StringBuffer();
        sb.append(url);
        if (url.contains("?")){
            if (url.indexOf("?")==url.length()-1){

            }else {
                sb.append("&");
            }
        }else {
            sb.append("?");
        }
        for (Map.Entry<String,String> entry:map.entrySet()){
            sb.append(entry.getKey())
                    .append("=")
                    .append(entry.getValue())
                    .append("&");
        }
        if (sb.indexOf("&")!=-1){
            sb.deleteCharAt(sb.lastIndexOf("&"));
        }
        OkHttpClient client = new OkHttpClient
                .Builder()
                .addInterceptor(new LoggingInterceptor())
                .build();
        Request request = new Request.Builder()
                .get()
                .url(sb.toString())
                .build();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, final IOException e) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        callBack.onFailed(tag,e);
                    }
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                final String result = response.body().string();
                //请求成功后做解析,通过自己的回调接口将数据返回去
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Object o;
                        if (TextUtils.isEmpty(result)){
                            o = null;
                        }else {
                            o = GsonUtils.getInstance().fromJson(result, cls);
                        }
                        callBack.onSuccess(tag,o);
                    }
                });
            }
        });


    }
}

HttpUtils-post请求

package com.bwie.com.myapplication.httputils;

import android.os.Handler;
import android.util.Log;

import com.bwie.com.myapplication.callback.CallBack;
import com.bwie.com.myapplication.interceptor.LoggingInterceptor;

import java.io.IOException;
import java.util.Map;

import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * Created by Wangrx on 2017/11/21.
 */

public class HttpUtils {
    private static final String TAG = "HttpUtils";
    private static volatile HttpUtils instance;

    private static Handler handler = new Handler();

    private HttpUtils() {

    }

    public static HttpUtils getInstance() {
        if (null == instance) {
            synchronized (HttpUtils.class) {
                if (instance == null) {
                    instance = new HttpUtils();
                }
            }
        }
        return instance;
    }
    /**
     * 封装的post请求
     *
     * @param url
     * @param map
     * @param callBack
     * @param cls
     */
    public void post(String url, Map<String, String> map, final CallBack callBack, final Class cls, final String tag) {
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(new LoggingInterceptor())
                .build();

        FormBody.Builder builder = new FormBody.Builder();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            builder.add(entry.getKey(), entry.getValue());
        }

        FormBody body = builder.build();

        final Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();

        Call call = client.newCall(request);
        call.enqueue(new okhttp3.Callback() {
            @Override
            public void onFailure(Call call, final IOException e) {
                Log.e(TAG, "onFailure: " + e.getCause().getStackTrace() + e.getMessage());
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        callBack.onFailed(tag,e);
                    }
                });

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String result = response.body().string();
                Log.i(TAG, "onResponse: " + result);

                final Object o = GsonUtils.getInstance().fromJson(result, cls);
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        callBack.onSuccess(tag,o);
                    }
                });
            }
        });
    }
}

CallBack

package com.bawei.com.wangruixin1509c20171113.callback;

/**
 * Created by Wangrx on 2017/11/13.
 */

public interface CallBack {
    void onSuccess(String tag,Object o);
    void onFailed(String tag,Exception e);
}
INewsView

package com.bawei.com.wangruixin1509c20171113.httputils;

import com.bawei.com.wangruixin1509c20171113.bean.JavaBean;

import java.util.List;

/**
 * Created by Wangrx on 2017/11/13.
 */

public interface INewsView {
    void success(String tag, List<JavaBean.DataBean> list);
    void failed(String tag,Exception e);
}
LoggingInterceptor拦截器

package com.bawei.com.wangruixin1509c20171113.httputils;

import java.io.IOException;

import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

/**
 * Created by 笔片 on 2017/10/16.
 * 网络拦截器
 */

public class LoggingInterceptor implements Interceptor{
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request original = chain.request();
        HttpUrl url=original.url().newBuilder()
                .addQueryParameter("source","android")
                .build();
        //添加请求头
        Request request = original.newBuilder()
                .url(url)
                .build();
        return chain.proceed(request);
    }

}
GsonUtils

package com.bawei.com.wangruixin1509c20171113.utils;

import com.google.gson.Gson;

/**
 * Created by Wangrx on 2017/11/13.
 */

public class GsonUtils {
    private static Gson instance;
        private GsonUtils(){

        }
        public static Gson getInstance(){
            if (instance==null){
                instance = new Gson();
            }
            return instance;
        }
}
NewsPresenter

package com.bawei.com.wangruixin1509c20171113.presenter;

import com.bawei.com.wangruixin1509c20171113.bean.JavaBean;
import com.bawei.com.wangruixin1509c20171113.callback.CallBack;
import com.bawei.com.wangruixin1509c20171113.httputils.HttpUtils;
import com.bawei.com.wangruixin1509c20171113.httputils.INewsView;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Wangrx on 2017/11/13.
 */

public class NewsPresenter {
    private INewsView inv;
    public void attachView(INewsView inv){
        this.inv = inv;
    }
    public void getNews(String show,int page){
        Map<String, String> map = new HashMap<>();
        map.put("keywords",show);
        map.put("page",page+"");
        HttpUtils.getInstance().get("http://120.27.23.105/product/searchProducts", map, new CallBack() {
            @Override
            public void onSuccess(String tag, Object o) {
                JavaBean bean = (JavaBean) o;
                if (bean != null){
                    List<JavaBean.DataBean> data = bean.getData();
                    inv.success(tag,data);

                }
            }

            @Override
            public void onFailed(String tag, Exception e) {
                inv.failed(tag,e);
            }
        }, JavaBean.class,"news");
    }
    public void detachView(){
        if (inv!=null){
            inv = null;
        }
    }


}
NewsListAdapter

package com.bawei.com.wangruixin1509c20171113.adapter;

import android.content.Context;
import android.graphics.Paint;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.bawei.com.wangruixin1509c20171113.R;
import com.bawei.com.wangruixin1509c20171113.bean.JavaBean;
import com.bumptech.glide.Glide;

import java.util.List;

/**
 * Created by Wangrx on 2017/11/13.
 */

public class NewsListAdapter extends RecyclerView.Adapter<NewsListAdapter.ViewHolder> {

    private Context context;
    private List<JavaBean.DataBean> list;
    private int count;
    public NewsListAdapter(Context context, List<JavaBean.DataBean> list,int count) {
        this.context = context;
        this.list = list;
        this.count = count;
    }
    private OnItemClickListener mOnItemClickListener;

    public interface OnItemClickListener{
        void onClick( int position);
        void onLongClick( int position);
    }
    public void setOnItemClickListener(OnItemClickListener onItemClickListener ){
        this. mOnItemClickListener=onItemClickListener;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (count==1){
            View v = View.inflate(context, R.layout.item, null);
            ViewHolder holder = new ViewHolder(v);
            return holder;
        }else if (count==2){
            View v = View.inflate(context, R.layout.item1, null);
            ViewHolder holder = new ViewHolder(v);
            return holder;

        }
        return null;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        String[] split = list.get(position).getImages().split("[|]");
        Glide.with(context).load(split[0]).into(holder.item_img);
        holder.item_bargainPrice.setText("原价:¥"+list.get(position).getBargainPrice());
        holder.item_bargainPrice.getPaint().setFlags(Paint. STRIKE_THRU_TEXT_FLAG); //下划线
        holder.item_bargainPrice.getPaint().setAntiAlias(true);//抗锯齿
        holder.item_price.setText("折扣价:¥"+list.get(position).getPrice());
        holder.item_title.setText(list.get(position).getTitle());
        if( mOnItemClickListener!= null){
            holder.itemView.setOnClickListener( new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mOnItemClickListener.onClick(position);
                }
            });
            holder. itemView.setOnLongClickListener( new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    mOnItemClickListener.onLongClick(position);
                    return false;
                }
            });
        }
    }

    @Override
    public int getItemCount() {
        if (list==null){
            return 0;
        }
        return list.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        private final ImageView item_img;
        private final TextView item_price;
        private final TextView item_bargainPrice;
        private final TextView item_title;

        public ViewHolder(View itemView) {
            super(itemView);
            item_img = itemView.findViewById(R.id.item_img);
            item_title = itemView.findViewById(R.id.item_title);
            item_price = itemView.findViewById(R.id.item_price);
            item_bargainPrice = itemView.findViewById(R.id.item_bargainPrice);
        }
    }
}
Main2Activity.java

package com.bawei.com.wangruixin1509c20171113;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class Main2Activity extends AppCompatActivity {

    private WebView web;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        Intent intent = getIntent();
        String url = intent.getStringExtra("url");
        web = (WebView) findViewById(R.id.web);
        web.loadUrl(url);
        web.setWebViewClient(new WebViewClient());

        WebSettings settings = web.getSettings();
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        settings.setJavaScriptEnabled(true);
    }
}
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="com.bawei.com.wangruixin1509c20171113.MainActivity">
    <TextView
        android:id="@+id/tv_show"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:text="搜索商品"
        android:textSize="25sp"
        android:gravity="center"
        />
    <ImageView
        android:id="@+id/right"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@mipmap/grid_icon"
        android:layout_alignParentRight="true"
        />
    <RelativeLayout
        android:id="@+id/rel"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_below="@+id/tv_show"
        android:layout_alignParentStart="true">
        <EditText
            android:id="@+id/et_sousuo"
            android:layout_width="300dp"
            android:layout_height="50dp"
            android:drawableLeft="@mipmap/a_4"
            android:hint="请输入关键字"
            />
        <Button
            android:id="@+id/btn_sousuo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/et_sousuo"
            android:text="搜索"
            />
    </RelativeLayout>
    <com.jwenfeng.library.pulltorefresh.PullToRefreshLayout
        android:layout_width="match_parent"
        android:id="@+id/mpull"
        android:layout_below="@+id/rel"
        android:layout_height="match_parent">
        <android.support.v7.widget.RecyclerView
            android:id="@+id/re_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"

            ></android.support.v7.widget.RecyclerView>

    </com.jwenfeng.library.pulltorefresh.PullToRefreshLayout>

</RelativeLayout>
activity_main2.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="com.bawei.com.wangruixin1509c20171113.Main2Activity">
    <WebView
        android:id="@+id/web"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></WebView>

</RelativeLayout>
item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">
    <ImageView
        android:id="@+id/item_img"
        android:layout_width="100dp"
        android:layout_height="100dp" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_toRightOf="@+id/item_img">

        <TextView
            android:id="@+id/item_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:text="title"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/item_bargainPrice"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/item_title"
            android:text="售价"
            android:layout_marginTop="10dp"
            android:textColor="#ccc"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/item_price"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/item_title"
            android:layout_marginLeft="10dp"
            android:layout_toRightOf="@+id/item_bargainPrice"
            android:text="售价"
            android:layout_marginTop="10dp"
            android:textColor="#f00"
            android:textSize="14sp"

            />

    </RelativeLayout>

</LinearLayout>
权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
依赖:

compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
compile 'com.squareup.okhttp3:okhttp:3.9.0'
compile 'com.google.code.gson:gson:2.8.2'
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.jwenfeng.pulltorefresh:library:1.0.3'

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值