一.使用场景,及业务需求
在Android项目开发中,为了让你的App能够连接后台服务器获取后台数据,在数据加载过程中弹出相应的"正在加载...."提示语,在网络或者服务器异常时请求失败弹出"加载失败,请重新请求",
二.写这篇博客原因
com.zhy:okhttputils:2.6.2'这个可以依赖的项目是Android大神鸿洋封装好的一个网络请求框架,我们可以把它集成到我们的项目中,为了更方便的使用它,我们需要在这个框架的基础上自定义MyOkhttpUtils再次封装,使我们的代码更优雅.
三.集成鸿洋的这个框架
1.在Android工程目录下的build.gradle文件中依赖
//okhttp3
implementation 'com.squareup.okhttp3:mockwebserver:3.11.0'
implementation 'com.squareup.okio:okio:2.0.0'
//鸿洋okhttputils
implementation 'com.zhy:okhttputils:2.6.2'
2.自定义MyApplication配置OkhttpClient
public class MyApplication extends Application
{
@Override
public void onCreate()
{
super.onCreate();
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new LoggerInterceptor("TAG"))
.connectTimeout(10000L, TimeUnit.MILLISECONDS)
.readTimeout(10000L, TimeUnit.MILLISECONDS)
//其他配置
.build();
OkHttpUtils.initClient(okHttpClient);
}
}
private void okhttpint(){
// 对Coolies进行持久化操作
final ClearableCookieJar cookieJar1 = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(getApplicationContext()));
// 对https支持,参数分别为:证书的inputstream 本地证书的inputstream 本地证书的密码
// 当前配置可以访问任何https网站
HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory(null, null, null);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(10000L, TimeUnit.MILLISECONDS) // 连接超时时间
.readTimeout(10000L, TimeUnit.MILLISECONDS) // 读取超时时间
.addInterceptor(new LoggerInterceptor("TAG"))
.cookieJar(cookieJar1)
.sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
// .sslSocketFactory(createSSLSocketFactory())
// .hostnameVerifier(new TrustAllHostnameVerifier())
.build();
OkHttpUtils.initClient(okHttpClient);
}
注意记得在清单文件中配置Application和网络权限
3.在工具类包下创建MyOkhttpUtils
public class MyOkhttpUtils {
public static final String TYPE_TXT = "txt";
public static final String TYPE_XLS = "xls";
public static final String TYPE_DOC = "doc";
public String sError = "网络连接失败";
public static void getRequest(String url, final OnRequestNetWorkListener mListener) {
OkHttpUtils
.get()
.url(url)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
mListener.notOk(e.getMessage());
DialogUtils.getInstance().dismiss();
}
@Override
public void onResponse(String response, int id) {
mListener.ok(response);
DialogUtils.getInstance().dismiss();
}
});
}
public static void postRequest(String url, HashMap<String, String> params, final OnRequestNetWorkListener listener) {
PostFormBuilder builder = OkHttpUtils.post().url(url);
Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = iterator.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
builder.addParams(key, value);
}
builder.build().execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
listener.notOk(e.getMessage());
DialogUtils.getInstance().dismiss();
}
@Override
public void onResponse(String response, int id) {
listener.ok(response);
DialogUtils.getInstance().dismiss();
}
});
}
/*
* 传输文件用这个
* */
public static void postRequestFile(String url, ArrayList<File> arrayListFile, String fileParameter, HashMap<String, String> params, final OnRequestNetWorkListener listener) {
PostFormBuilder builder = OkHttpUtils.post().url(url);
Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = iterator.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
builder.addParams(key, value);
}
if (arrayListFile.size() == 0) { //如果是空新建空文件
//新建一个File类型的成员变量,传入文件名路径。
File file = new File("/mnt/sdcard/wlgj.txt");
//判断文件是否存在,存在就删除
if (file.exists()) {
file.delete();
}
try {
//创建文件
file.createNewFile();
//给一个吐司提示,显示创建成功
} catch (IOException e) {
e.printStackTrace();
}
builder.addFile(fileParameter, file.getName(), file); //调用 addFile 方法上传文件
} else {
for (int i = 0; i < arrayListFile.size(); i++) { //遍历存储文件的集合
File file = arrayListFile.get(i);
builder.addFile(fileParameter, file.getName(), file); //调用 addFile 方法上传文件
}
}
builder.build().execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
listener.notOk(e.getMessage());
DialogUtils.getInstance().dismiss();
}
@Override
public void onResponse(String response, int id) {
listener.ok(response);
DialogUtils.getInstance().dismiss();
}
});
}
/*
* 一个页面有两个 DialogUtils.getInstance().dismiss(); 会冲突
* 物资供应看板三级界面
* */
public static void postRequestNoDialog(String url, HashMap<String, String> params, final OnRequestNetWorkListener listener) {
PostFormBuilder builder = OkHttpUtils.post().url(url);
Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = iterator.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
builder.addParams(key, value);
}
builder.build().execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
listener.notOk(e.getMessage());
}
@Override
public void onResponse(String response, int id) {
listener.ok(response);
}
});
}
/**
* 下载文件
*/
public void downloadFile(final List<String> pathList, List<String> title, final int postion, final Context context) {
// 为RequestParams设置文件下载后的保存路径
String url = pathList.get(postion);
System.out.println("文件下载:" + url);
final String savePath = FilePathUtils.init(context).getFileSaveDir().getAbsolutePath() + url.substring(url.lastIndexOf("/"), url.length());
System.out.println("savePath:" + savePath);
HttpUtils utils = new HttpUtils();
utils.download(url, savePath, true, false, new RequestCallBack<File>() {
@Override
public void onSuccess(ResponseInfo<File> responseInfo) {
Log.d("=====", "=====a下载成功======");
if (pathList.get(postion).contains(TYPE_TXT)) {
Intent intent = new Intent();
File file = new File(savePath);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), ".txt");
try {
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(context, "您没有安装打开此文件的软件,请安装后再次打开", Toast.LENGTH_SHORT).show();
}
} else if (pathList.get(postion).contains(TYPE_XLS)) {
Intent intent = new Intent();
File file = new File(savePath);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), ".xls");
try {
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(context, "您没有安装打开此文件的软件,请安装后再次打开", Toast.LENGTH_SHORT).show();
}
} else if (pathList.get(postion).contains(TYPE_DOC)) {
Intent intent = new Intent();
File file = new File(savePath);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), ".doc");
try {
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(context, "您没有安装打开此文件的软件,请安装后再次打开", Toast.LENGTH_SHORT).show();
}
} else {
ToastUtils.toast(context, "不是以上的类型");
}
}
@Override
public void onFailure(HttpException e, String s) {
Log.d("=====", "=====下载失败======" + s + e.getMessage());
DialogUtils.getInstance().dismiss();
}
@Override
public void onLoading(long total, long current, boolean isUploading) {
super.onLoading(total, current, isUploading);
Log.d("====下载中==", total + "," + current);
}
@Override
public void onStart() {
super.onStart();
Log.d("=====", "=====apk开始下载======");
}
});
// //下载路径
// final String url = pathList.get(postion);
// Request request = new Request.Builder().url(pathList.get(postion)).build();
// new OkHttpClient().newCall(request).enqueue(new Callback() {
// @Override
// public void onFailure(Call call, IOException e) {
// // 下载失败
// e.printStackTrace();
// ToastUtils.toast(context, "下载失败,请重新下载");
// }
//
// @Override
// public void onResponse(Call call, Response response) throws IOException {
// Sink sink = null;
// BufferedSink bufferedSink = null;
// try {
// String mSDCardPath = Environment.getExternalStorageDirectory().getAbsolutePath();
// File dest = new File(mSDCardPath, url.substring(url.lastIndexOf("/") + 1));
// sink = Okio.sink(dest);
// bufferedSink = Okio.buffer(sink);
// bufferedSink.writeAll(response.body().source());
// bufferedSink.close();
// if (pathList.get(postion).contains(TYPE_TXT)) {
// Intent intent = new Intent("android.intent.action.VIEW");
// intent.addCategory("android.intent.category.DEFAULT");
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Uri uri2 = Uri.fromFile(new File(pathList.get(postion)));
// intent.setDataAndType(uri2, "text/plain");
// context.startActivity(intent);
// } else if (pathList.get(postion).contains(TYPE_XLS)) {
// Intent intent = new Intent("android.intent.action.VIEW");
// intent.addCategory("android.intent.category.DEFAULT");
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Uri uri = Uri.fromFile(new File(pathList.get(postion)));
// intent.setDataAndType(uri, "application/vnd.ms-excel");
// context.startActivity(intent);
// } else if (pathList.get(postion).contains(TYPE_DOC)) {
// Intent intent = new Intent("android.intent.action.VIEW");
// intent.addCategory("android.intent.category.DEFAULT");
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Uri uri = Uri.fromFile(new File(pathList.get(postion)));
// intent.setDataAndType(uri, "application/msword");
// context.startActivity(intent);
// } else {
// ToastUtils.toast(context, "不是以上的类型");
// }
// } catch (Exception e) {
// e.printStackTrace();
// } finally {
// if (bufferedSink != null) {
// bufferedSink.close();
// }
//
// }
// }
// });
}
OnRequestNetWorkListener listener;
public void setOnRequestNetWorkListener(OnRequestNetWorkListener listener) {
this.listener = listener;
}
public interface OnRequestNetWorkListener {
void notOk(String err);
void ok(String response);
}
}
4.DialogUtils
public class DialogUtils {
private static Dialog dialog;
private static DialogUtils du;
public DialogUtils() {
}
public static DialogUtils getInstance() {
if (du == null) {
du = new DialogUtils();
}
return du;
}
public void showDialog(Context context, String content) {
int width = ScreenSize.screenWidth(context);
LayoutParams params = new LayoutParams(width / 3, width / 3);
LayoutInflater inflater = LayoutInflater.from(context);
dialog = new Dialog(context, R.style.MyDialogStyle);
View v = inflater.inflate(R.layout.dialog, null);
TextView tv = (TextView) v.findViewById(R.id.textViewContent);
tv.setText(content);
dialog.setContentView(v, params);
dialog.show();
System.out.println("-----进入执行----showDialog");
}
public boolean isShow(){
System.out.println("-----进入----isShow");
if (dialog!=null){
return dialog.isShowing();
}else {
return false;
}
}
public void dismiss() {
System.out.println("-----进入----dismiss()");
if (dialog != null) {
dialog.dismiss();
System.out.println("---执行------dismiss");
}
}
}
<!-- 加载进度匡========================================================================== -->
<style name="MyDialogStyle">
<!-- 背景透明 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 边框 -->
<item name="android:windowFrame">@null</item>
<!-- 无标题 -->
<item name="android:windowNoTitle">true</item>
<!-- 是否浮现在activity之上 -->
<item name="android:windowIsFloating">true</item>
<!-- 半透明 -->
<item name="android:windowIsTranslucent">true</item>
<!-- 内容覆盖 -->
<item name="android:windowContentOverlay">@null</item>
<!-- 窗口样式Dialog -->
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<!-- 模糊 -->
<item name="android:backgroundDimEnabled">true</item>
</style>
dialog.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.8"
android:background="@drawable/dialog_backgroud"
android:gravity="center"
android:orientation="vertical">
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progress"
android:layout_width="80dp"
android:layout_height="30dp" />
<TextView
android:id="@+id/textViewContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:singleLine="true"
android:textColor="@android:color/white"
android:textSize="16sp" />
</LinearLayout>
dialog_backgroud.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<corners android:radius="5dp" />
<solid android:color="@android:color/black" />
</shape>
</item>
</selector>
5.ToastUtils
public class ToastUtils {
public static Toast toast(Context context, String text) {
Toast tos=Toast.makeText(context, text, Toast.LENGTH_SHORT);
tos.show();
return tos;
}
public void cancelToast(Toast toast) {
if (toast != null) {
toast.cancel();
}
}
}
6.获取屏幕尺寸ScreenSize
public class ScreenSize {
/**
* 手机屏幕的宽
*
* @return
*/
public static int screenWidth(Context context) {
Activity activity = (Activity) context;
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
return dm.widthPixels;
}
/**
* 手机屏幕的高
*
* @return
*/
public static int screenHeight(Context context) {
Activity activity = (Activity) context;
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
return dm.heightPixels;
}
public static int dp2px(int dpVal, Context context) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, context.getResources().getDisplayMetrics());
}
public static int sp2px(int spVal, Context context) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
spVal, context.getResources().getDisplayMetrics());
}
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
}
四.在项目使用
DialogUtils.getInstance().showDialog(getContext(), "加载中...");
MyOkhttpUtil.postRequest(Constant.APP_URL + "houseTypeList", map, new MyOkhttpUtil.OnRequestNetWorkListener() {
@Override
public void notOk(String err) {
new Throwable("请求失败");
}
@Override
public void ok(String response) {
JSONObject jsonObject;
try {
Log.e("Tag","丝路会展:"+response);
jsonObject= new JSONObject(response);
String status = jsonObject.getString("status");
Log.e("TAG",status);
if (status.equals("1")){
String data = jsonObject.getString("data");
Log.e("TAG",data);
JSONObject info = new JSONObject(data);
//户型列表
getHouseTypeList(info);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}