
实例:使用OKGO下载网络压缩包资源,然后解压缩放在本地使用
发布日期:2021-05-08 00:50:46
浏览次数:9
分类:原创文章
本文共 12422 字,大约阅读时间需要 41 分钟。
一,前期基础知识储备
1)svg图片较大,所以需要压缩为zip包后放在服务器上,下载使用;
2)使用OKGO库进行网络资源下载;
3)使用工具库Blankj中的解压缩工具进行解压缩后,然后保存在本地;
4)下载并且解压缩zip成功后,删除本地zip包,只保留解压缩得到的svg资源。
二,上代码,具体实现
1)引入OKGO和Blankj依赖:
implementation 'com.lzy.net:okgo:3.0.4'implementation 'com.blankj:utilcode:1.25.9'
注:如果有使用RxJava的依赖,OKGO的依赖需要进行修改;另外此库已经停止维护。
2)使用OKGO前需要进行的声明:
OkHttpClient.Builder builder = new OkHttpClient.Builder(); //全局的读取超时时间 builder.readTimeout(30000L, TimeUnit.MILLISECONDS); //全局的写入超时时间 builder.writeTimeout(30000L, TimeUnit.MILLISECONDS); //全局的连接超时时间 builder.connectTimeout(100000L, TimeUnit.MILLISECONDS); builder.proxy(Proxy.NO_PROXY); builder.hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { try { if (TextUtils.isEmpty(hostname) || TextUtils.isEmpty(session.getPeerHost())) { return false; } return hostname.equals(session.getPeerHost()); } catch (Exception e) { return false; } } }); OkGo.getInstance().init(this).setOkHttpClient(builder.build()).setRetryCount(3);
库已停止维护,所以后续随着targetSdkVersion的升级,声明也需要自己做出相应修改。博主应用版本为29。
3)下载zip包的代码实现:
private void onDownLoadAndSaveSvg(String svgUrl, String svgName) { if (NetCheckUtils.isNetWorkEnable(this)) { /*Api29 Android10 存储结构有变 需要进行其他处理*/ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { OkGo.<File>get(svgUrl) .execute(new FileCallback(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + File.separator + "lovedrawing", svgName + ".zip") { @Override public void onSuccess(Response<File> response) { Log.d(TAG, "onSuccess: file 下载成功"); isDownLoad = true; String zipFileName = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + File.separator + "lovedrawing" + File.separator + svgName + ".zip"; svgUnzipPath = ZipAndReadSvgUtils.unZipDownlaodSvgToSdCard(PaintActivity.this, zipFileName, svgName); File f = response.body(); if (f != null && f.exists()) { f.delete(); } InputStream mInputStream = ZipAndReadSvgUtils.readSvgFromSdCard(PaintActivity.this, svgName); if (mInputStream != null) { parseSvgXml(mInputStream); drawingBoardView.init(PaintActivity.this, mInputStream); initColorRecyData(); initPopuWindowLayout(); } else { } noNetWorkRl.setVisibility(View.GONE); } @Override public void onError(Response<File> response) { Log.d(TAG, "onError: file出错,," + response + ",," + response.body() + ",," + response.message() + ",," + response.getException() + ",," + response.isSuccessful()); noNetWorkRl.setVisibility(View.VISIBLE); } @Override public void downloadProgress(Progress progress) { Log.d(TAG, "downloadProgress: 下载过程,," + progress.totalSize + ",," + progress); } }); } else { onMIUIDownLoadAndSaveSvg(svgUrl, svgName); } } else { noNetWorkRl.setVisibility(View.VISIBLE); ToastUtil.showToast(PaintActivity.this, R.string.net_fail); } }
因为API29 的存储结构发生变化,所以需要单独再做一次下载处理,代码如下:
private void onMIUIDownLoadAndSaveSvg(String svgUrl, String svgName) { File tempFile = getExternalFilesDir("TempProject"); OkGo.<File>get(svgUrl) .execute(new FileCallback((tempFile != null ? tempFile.getAbsolutePath() : null) + File.separator + "lovedrawing", svgName + ".zip") { @Override public void onSuccess(Response<File> response) { Log.d(TAG, "onSuccess: MIUI file 下载成功"); isDownLoad = true; String zipFileName = null; if (tempFile != null) { zipFileName = tempFile.getAbsolutePath() + File.separator + "lovedrawing" + File.separator + svgName + ".zip"; } svgUnzipPath = ZipAndReadSvgUtils.unZipDownlaodSvgToSdCard(PaintActivity.this, zipFileName, svgName); File f = response.body(); if (f != null && f.exists()) { f.delete(); } InputStream mInputStream = ZipAndReadSvgUtils.readSvgFromSdCard(PaintActivity.this, svgName); if (mInputStream != null) { parseSvgXml(mInputStream); drawingBoardView.init(PaintActivity.this, mInputStream); initColorRecyData(); initPopuWindowLayout(); } else { } noNetWorkRl.setVisibility(View.GONE); } @Override public void onError(Response<File> response) { Log.d(TAG, "onError: MIUI file出错,," + response + ",," + response.body() + ",," + response.message() + ",," + response.getException() + ",," + response.isSuccessful()); noNetWorkRl.setVisibility(View.VISIBLE); } @Override public void downloadProgress(Progress progress) { Log.d(TAG, "downloadProgress: MIUI 下载过程,," + progress.totalSize + ",," + progress); } }); }
内部代码解析:
①svgUrl —— 即为放置svg zip包的网络服务器地址;
②下载成功后,将得到的zip包保存在本地的地址如下:
new FileCallback(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath()+ File.separator + "lovedrawing", svgName + ".zip")
③得到zip包,利用工具类进行解压缩,然后将下载好的zip进行删除:
String zipFileName = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + File.separator + "lovedrawing" + File.separator + svgName + ".zip"; svgUnzipPath = ZipAndReadSvgUtils.unZipDownlaodSvgToSdCard(PaintActivity.this, zipFileName, svgName); File f = response.body(); if (f != null && f.exists()) { f.delete(); }
4)使用到的ZipAndReadSvgUtils 解压缩工具类如下:
public class ZipAndReadSvgUtils { private static final String TAG = "ZipAndReadSvgUtils"; private static final String SVGFILENAME = "_localSvg"; /** * 正式项目中使用——解压缩网络下好的SVG * @param context * @param zipFileName * @param svgName */ public static String unZipDownlaodSvgToSdCard(Context context, String zipFileName, String svgName) { String svgUnzipPath = ""; File zipFile = new File(zipFileName); Log.d(TAG, "unZipDownlaodSvgToSdCard: 压缩文件所在地址," + zipFile.getAbsolutePath()); String fileName = ""; File saveJsonFile = context.getExternalFilesDir("netToLocalSvg"); if (saveJsonFile != null) { fileName = saveJsonFile.getAbsolutePath() + File.separator + svgName + SVGFILENAME; } File file = new File(fileName); try { ZipUtils.unzipFile(zipFile, file); List<File> files = FileUtils.listFilesInDir(file); svgUnzipPath = files.get(0).getAbsolutePath(); Log.d(TAG, "unZipDownlaodSvgToSdCard: SVG解压缩文件地址," + files.get(0).getAbsolutePath()); } catch (IOException e) { e.printStackTrace(); } return svgUnzipPath; } /** * 正式项目中使用——读取存在本地SDCard下的SVG * @param context * @return */ public static InputStream readSvgFromSdCard(Context context, String svgName) { String fileName = ""; File saveJsonFile = context.getExternalFilesDir("netToLocalSvg"); if (saveJsonFile != null) { fileName = saveJsonFile.getAbsolutePath() + File.separator + svgName + SVGFILENAME; } File file = new File(fileName); InputStream is = null; try { List<File> files= FileUtils.listFilesInDir(file); Log.d(TAG, "readSvgFromSdCard: 读," + files.get(0)); String svgString = FileIOUtils.readFile2String(files.get(0)); is = ConvertUtils.string2InputStream(svgString, "UTF-8"); Log.d(TAG, "readSvgFromSdCard: 读取本地存储svg流为," + is); } catch (Exception e) { e.printStackTrace(); } return is; }}
最终得到svg资源地址:
/storage/emulated/0/Android/data/com.love.drawing.draw/files/netToLocalSvg/animal_010_localSvg/animal_010.svg
三,知识延伸
自定义View中动态添加 父容器布局 —— 采用静态布局的形式添加
下面代码中的自定义View继承自帧布局 FrameLayout 。
FrameLayout.LayoutParams lp = new LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.TOP | Gravity.END); lp.setMargins(0, ConvertUtils.dp2px(64), width + ConvertUtils.dp2px(6), 0); LayoutInflater inflater3 = LayoutInflater.from(mContext); preControlLl = inflater3.inflate(R.layout.view_preview_ll, null); LinearLayout closeRoot = preControlLl.findViewById(R.id.close_root); TextView closeText = preControlLl.findViewById(R.id.close_text); closeText.setTypeface(Typeface.createFromAsset(mContext.getAssets(), "fonts/Roboto-Regular.ttf")); ImageView closeImg = preControlLl.findViewById(R.id.close_img); closeRoot.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { ... ... } }); preControlLl.setLayoutParams(lp); addView(preControlLl);
注:使用 LayoutParams 动态指定父容器的大小,位置,边距等信息。
静态布局 view_preview_ll 如下:
<?xml version="1.0" encoding="utf-8"?><com.game.jianbihua.view.RadiusCardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="wrap_content" android:layout_height="25dp" app:cardMaxElevation="4dp" app:rcv_bottomLeftRadiu="3dp" app:rcv_topLeftRadiu="3dp"> <LinearLayout android:id="@+id/close_root" android:layout_width="wrap_content" android:layout_height="25dp" android:layout_gravity="top|end" android:background="@color/home_coins" android:gravity="center" android:orientation="horizontal"> <ImageView android:id="@+id/close_img" android:layout_width="6dp" android:layout_height="12dp" android:layout_gravity="center_vertical" android:layout_marginStart="4dp" android:scaleType="fitCenter" android:src="@drawable/view_pre_left" /> <TextView android:id="@+id/close_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginStart="4dp" android:layout_marginEnd="4dp" android:gravity="center" android:text="Preview" android:textColor="@color/pureWhite" android:textSize="12sp" /> </LinearLayout></com.game.jianbihua.view.RadiusCardView>
发表评论
最新留言
关注你微信了!
[***.104.42.241]2025年04月06日 18时49分00秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
【模拟】优美三角剖分
2021-05-07
【普及模拟】交换
2021-05-07
4*4矩阵键盘的FPGA驱动
2021-05-07
椭圆曲线密码系统——椭圆曲线
2021-05-07
Vue实现选项卡功能
2021-05-07
数据结构——链表
2021-05-07
[编程题]Course List for Student (25)
2021-05-07
【Python】面向对象,封装
2021-05-07
接口又是个啥?
2021-05-07
5.11 TEST1
2021-05-07
uni-app请求头中携带token
2021-05-07
常用的 Git 命令和小技巧(1)
2021-05-07
vue中接收后台的图片验证码并显示
2021-05-07
springboot入门(1)---整合MyBatis
2021-05-07
Vue入门学习笔记(1)
2021-05-07
ECharts——双向柱状图
2021-05-07
Vue——引进bootstrap
2021-05-07
Vue——引进ivew
2021-05-07
趣谈win10常用快捷键
2021-05-07