Android网络拦截器,支持Debug模式,查看请求与响应的具体信息并修改
2017-12-05 10:00
477 查看
上班的某天,导师突然对我说要做一个网络拦截器
网络拦截器,顾名思义就是用于拦截网络的,可以获得 http请求的具体信息,如请求头,URL,请求体,响应体,请求方法等,
一开始万脸懵逼,根本就没接触过这么高深的东西,于是各种百度,一无所获,看来是没人做过类似的插件。
于是师傅提供了一个思路,OkHttp有一个Interceptor 用于拦截网络,修改请求等,了解之后就开始做了
前期准备:全局悬浮窗,跟随应用一起消亡;一个界面,用于展示网络请求信息;
项目中涉及的知识比较多,比如Service,windowmanager,recyclerview,okhttpinterceptor,数据的存储等 下面将一个个细说
先看图,黄色的小点就是悬浮窗,全局存在,因此用到了bindService
要实现全局的悬浮窗,自然用到了Service,后台一直存在,将生成的界面展示再Window上,
这里用到了WindowManager 和Service,通过layoutinfalte加载自定义的界面,然后通过windowmanager.addView()把自定义布局加载到window中,至于点击事件什么的,很简单
private void initSwitchWindow() {
switchParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
switchParams.gravity = Gravity.START | Gravity.TOP;
switcherWindow = LayoutInflater.from(this)
.inflate(R.layout.interceptor_switch_btn, null);
mWindowManager.addView(switcherWindow, switchParams);
pgbNetWorking = (ProgressBar) switcherWindow.findViewById(R.id.pgb_on_working);
tvProgress = (TextView) switcherWindow.findViewById(R.id.tv_progress);
switcherWindow.setOnTouchListener(new SwitchOnTouchListener(switcherWindow, mWindowManager));
switcherWindow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (networkWindow == null) {
initNetWorkWindow();
showLog();
a11e
} else if (!isLogShow) {
showLog();
} else {
closeLog();
}
}
});
switcherWindow.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (checkFunctionWindow == null) {
initCheckedDetailWindow();
showFunctionWindow();
} else if (!isCheckFunctionShow) {
showFunctionWindow();
}
Log.i("tag", "-----onlongclick");
return true;
}
});
}悬浮窗初始化好了之后 就是点击后展示的界面,这里用到了RecyclerView,点击后出现子View
这里的recyclerview将会通过getItemViewType来设置,在bindviewHolder的时候 判断传入的viewholder属于是什么类型,从而展示相应信息
/**
* d
* 适配器用于将网络拦截器中的信息展示到RecyclerView上
* Created by HongChen on 2017/11/8.
*/
public class LogAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<HttpVO> realHttpVOS = new ArrayList<>();
private List<HttpVO> showHttpVOS = new ArrayList<>();
private OnItemClickListener onItemClickListener;
public interface OnItemClickListener {
boolean onLongClick(View v, int position);
}
public void setOnItemLongClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
/*
点击父布局出现详细信息
*/
if (viewType == HttpVO.TYPE_TITLE) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.parentview_layout, parent, false);
return new ParentViewHolder(view);
} else {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.childview_layout, parent, false);
return new ChildViewHolder(view);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final HttpVO httpVO = showHttpVOS.get(position);
if (holder instanceof ParentViewHolder) {
String title = "Url:" + httpVO.content;
((ParentViewHolder) holder).title.setText(title);
} else if (holder instanceof ChildViewHolder) {
((ChildViewHolder) holder).content.setText(httpVO.content);
((ChildViewHolder) holder).content.setTag(httpVO.position);
}
}
@Override
public int getItemCount() {
return showHttpVOS.size();
}
@Override
public int getItemViewType(int position) {
return showHttpVOS.get(position).type;
}
public void addData(List<HttpVO> data) {
realHttpVOS.addAll(data);
showHttpVOS.add(data.get(0));
notifyItemInserted(showHttpVOS.size() - 1);
}
/**
* 清空所有数据
*/
public void clearData() {
realHttpVOS.clear();
showHttpVOS.clear();
notifyDataSetChanged();
}
public List<HttpVO> getDataList() {
return realHttpVOS;
}
class ParentViewHolder extends RecyclerView.ViewHolder {
TextView title;
ParentViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.tv_title);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final int position = getAdapterPosition();
final HttpVO httpVO = showHttpVOS.get(position);
final boolean isExpand = httpVO.isExpand();
httpVO.setExpand(!isExpand);
final int nextPosition = position + 1;
if (isExpand) {
showHttpVOS.remove(nextPosition);
notifyItemRemoved(nextPosition);
} else {
showHttpVOS.add(nextPosition, realHttpVOS.get(httpVO.position + 1));
notifyItemInserted(nextPosition);
}
}
});
}
}
class ChildViewHolder extends RecyclerView.ViewHolder {
TextView content;
RelativeLayout rlVerifyRequestData;
EditText etUpdate;
Button btnVerify;
ChildViewHolder(final View itemView) {
super(itemView);
content = (TextView) itemView.findViewById(R.id.tv_content);
rlVerifyRequestData = (RelativeLayout) itemView.findViewById(R.id.rl_verify_requestdata);
etUpdate = (EditText) itemView.findViewById(R.id.et_verifydata);
btnVerify = (Button) itemView.findViewById(R.id.btn_updata);
content.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Log.i("tag", "----------onLongClick");
return onItemClickListener != null && onItemClickListener.onLongClick(v, (Integer) v.getTag());
}
});
}
}
}先写这点,要上班了
网络拦截器,顾名思义就是用于拦截网络的,可以获得 http请求的具体信息,如请求头,URL,请求体,响应体,请求方法等,
一开始万脸懵逼,根本就没接触过这么高深的东西,于是各种百度,一无所获,看来是没人做过类似的插件。
于是师傅提供了一个思路,OkHttp有一个Interceptor 用于拦截网络,修改请求等,了解之后就开始做了
前期准备:全局悬浮窗,跟随应用一起消亡;一个界面,用于展示网络请求信息;
项目中涉及的知识比较多,比如Service,windowmanager,recyclerview,okhttpinterceptor,数据的存储等 下面将一个个细说
先看图,黄色的小点就是悬浮窗,全局存在,因此用到了bindService
要实现全局的悬浮窗,自然用到了Service,后台一直存在,将生成的界面展示再Window上,
这里用到了WindowManager 和Service,通过layoutinfalte加载自定义的界面,然后通过windowmanager.addView()把自定义布局加载到window中,至于点击事件什么的,很简单
private void initSwitchWindow() {
switchParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
switchParams.gravity = Gravity.START | Gravity.TOP;
switcherWindow = LayoutInflater.from(this)
.inflate(R.layout.interceptor_switch_btn, null);
mWindowManager.addView(switcherWindow, switchParams);
pgbNetWorking = (ProgressBar) switcherWindow.findViewById(R.id.pgb_on_working);
tvProgress = (TextView) switcherWindow.findViewById(R.id.tv_progress);
switcherWindow.setOnTouchListener(new SwitchOnTouchListener(switcherWindow, mWindowManager));
switcherWindow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (networkWindow == null) {
initNetWorkWindow();
showLog();
a11e
} else if (!isLogShow) {
showLog();
} else {
closeLog();
}
}
});
switcherWindow.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (checkFunctionWindow == null) {
initCheckedDetailWindow();
showFunctionWindow();
} else if (!isCheckFunctionShow) {
showFunctionWindow();
}
Log.i("tag", "-----onlongclick");
return true;
}
});
}悬浮窗初始化好了之后 就是点击后展示的界面,这里用到了RecyclerView,点击后出现子View
这里的recyclerview将会通过getItemViewType来设置,在bindviewHolder的时候 判断传入的viewholder属于是什么类型,从而展示相应信息
/**
* d
* 适配器用于将网络拦截器中的信息展示到RecyclerView上
* Created by HongChen on 2017/11/8.
*/
public class LogAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<HttpVO> realHttpVOS = new ArrayList<>();
private List<HttpVO> showHttpVOS = new ArrayList<>();
private OnItemClickListener onItemClickListener;
public interface OnItemClickListener {
boolean onLongClick(View v, int position);
}
public void setOnItemLongClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
/*
点击父布局出现详细信息
*/
if (viewType == HttpVO.TYPE_TITLE) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.parentview_layout, parent, false);
return new ParentViewHolder(view);
} else {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.childview_layout, parent, false);
return new ChildViewHolder(view);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final HttpVO httpVO = showHttpVOS.get(position);
if (holder instanceof ParentViewHolder) {
String title = "Url:" + httpVO.content;
((ParentViewHolder) holder).title.setText(title);
} else if (holder instanceof ChildViewHolder) {
((ChildViewHolder) holder).content.setText(httpVO.content);
((ChildViewHolder) holder).content.setTag(httpVO.position);
}
}
@Override
public int getItemCount() {
return showHttpVOS.size();
}
@Override
public int getItemViewType(int position) {
return showHttpVOS.get(position).type;
}
public void addData(List<HttpVO> data) {
realHttpVOS.addAll(data);
showHttpVOS.add(data.get(0));
notifyItemInserted(showHttpVOS.size() - 1);
}
/**
* 清空所有数据
*/
public void clearData() {
realHttpVOS.clear();
showHttpVOS.clear();
notifyDataSetChanged();
}
public List<HttpVO> getDataList() {
return realHttpVOS;
}
class ParentViewHolder extends RecyclerView.ViewHolder {
TextView title;
ParentViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.tv_title);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final int position = getAdapterPosition();
final HttpVO httpVO = showHttpVOS.get(position);
final boolean isExpand = httpVO.isExpand();
httpVO.setExpand(!isExpand);
final int nextPosition = position + 1;
if (isExpand) {
showHttpVOS.remove(nextPosition);
notifyItemRemoved(nextPosition);
} else {
showHttpVOS.add(nextPosition, realHttpVOS.get(httpVO.position + 1));
notifyItemInserted(nextPosition);
}
}
});
}
}
class ChildViewHolder extends RecyclerView.ViewHolder {
TextView content;
RelativeLayout rlVerifyRequestData;
EditText etUpdate;
Button btnVerify;
ChildViewHolder(final View itemView) {
super(itemView);
content = (TextView) itemView.findViewById(R.id.tv_content);
rlVerifyRequestData = (RelativeLayout) itemView.findViewById(R.id.rl_verify_requestdata);
etUpdate = (EditText) itemView.findViewById(R.id.et_verifydata);
btnVerify = (Button) itemView.findViewById(R.id.btn_updata);
content.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Log.i("tag", "----------onLongClick");
return onItemClickListener != null && onItemClickListener.onLongClick(v, (Integer) v.getTag());
}
});
}
}
}先写这点,要上班了
相关文章推荐
- mysql查看是否支持分区以及查看具体某一表的详细分区信息情况
- curl -v www.linode.com查看请求及响应信息
- iOS iOS9下修改回HTTP模式进行网络请求
- 【Android网络开发】(一)HTTP请求报文和HTTP响应报文
- 查看Android支持的硬解码信息
- 修改httpcore.jar的源码,查看Httpclient的http协议请求头部和响应头部
- android获取URLConnection和HttpClient网络请求响应码
- 用Fiddler查看 Android/iOS 网络请求
- iOS9后修改HTTP模式进行网络请求
- Android支持单词提示搜索框的网络请求策略
- HTTP基础(一):如何使用浏览器network查看请求和响应的信息
- android获取URLConnection和HttpClient网络请求响应码
- 用Fiddler查看 Android/iOS 网络请求
- 网络请求工具类之OkHttp3封装(支持缓存、日志、拦截器、断点下载、上传等)
- android获取URLConnection和HttpClient网络请求响应码
- Android网络请求图片缓存本地无OOM支持安卓7.0
- Android 首选网络模式默认值的修改方法
- Android三大设计模式之一------------------MVP设计模式(包括rxjava+retrofit网络请求框架)
- AndroidInject项目使用动态代理增加对网络请求的支持
- 查看AFnetworking网络请求时服务器返回的头部信息