
实例:下载服务器zip资源(Json,Png,多种文件)
发布日期:2021-05-08 00:50:48
浏览次数:26
分类:原创文章
本文共 14502 字,大约阅读时间需要 48 分钟。
一、前期基础知识储备
1)OKGO库地址:
作者已停止维护,所以使用时需要在文档基础上,做必要的修改。
2)笔者用以下载服务器上一些简单的资源,比如Json,Png,这些资源都是打包成zip包的形式,尽量减小包体,便以传输。
3)由于是zip的形式传输,所以资源下载到本地之后,会有一个解压缩保存本地的过程,解压缩完毕得到对应资源后,需要删去zip包。
4)涉及到Json解析的时候,使用Gson库进行解析。
二、上代码,具体实现
1)引入依赖库;
def gsonVersion = "2.6.2" def okgoVersion = "3.0.4" implementation "com.google.code.gson:gson:$gsonVersion" // 解析Gson implementation "com.lzy.net:okgo:$okgoVersion" // 下载资源 implementation "com.blankj:utilcode:1.25.9" // 万能工具库
2)初始化OKGO;
public class ArtApp extends Application { @Override public void onCreate() { super.onCreate(); if (isMainProcess()) { 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); } } private String getCurrentProcessName() { int pid = android.os.Process.myPid(); String processName = ""; ActivityManager manager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); for (ActivityManager.RunningAppProcessInfo process : manager.getRunningAppProcesses()) { if (process.pid == pid) { processName = process.processName; } } return processName; } public boolean isMainProcess() { return getApplicationContext().getPackageName().equals(getCurrentProcessName()); }}
进入Android 29之后,OKGO需要补充一些声明,要不然会遇到一些 HostnameVerifier 错误;
3)Manifest文件中新增;
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <application android:name=".ArtApp" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> ... ... </application>
①需要新增两项权限,后续需要了解网络状态,以做出不同的处理;
②处理不安全的网络访问,由于资源是放在“http”下,需要做下面处理,要不然访问不到;
android:requestLegacyExternalStorage="true"android:usesCleartextTraffic="true"
4)下载一份放置Png的zip包;
private static final String URL = "http://121.40.46.187/ts_paint_color/texture_001_png.zip"; private static final String FILENAME = "templatePng"; onDownLoadAndSavePNG(URL, "texture_001_png"); /*下载填充用的纹理图片*/ private void onDownLoadAndSavePNG(String pngUrl, final String fileName) { if (Utils.isNetWorkEnable(this)) { OkGo.<File>get(pngUrl) .execute(new FileCallback(this.getExternalFilesDir(FILENAME).getAbsolutePath() + File.separator, fileName + ".zip") { @Override public void onSuccess(com.lzy.okgo.model.Response<File> response) { String zipFileName = getExternalFilesDir(FILENAME).getAbsolutePath() + File.separator + File.separator + fileName + ".zip"; String svgUnzipPath = ZipAndReadJsonUtils.unZipDownlaodSvgToSdCard(OkgoActivity.this, zipFileName); txt.setText(svgUnzipPath); File f = response.body(); if (f != null && f.exists()) { Log.d(TAG, "onSuccess: file_Download success file exists 11,," + svgUnzipPath); /*/storage/emulated/0/Android/data/camera.editor.art.paintsplash/files/templatePng/texture_001_png.zip*/ String jsonPath = getExternalFilesDir(FILENAME).getAbsolutePath() + File.separator + fileName; Log.d(TAG, "onSuccess: file_Download success file exists 22,," + jsonPath); /*/storage/emulated/0/Android/data/camera.editor.art.paintsplash/files/templatePng/texture_001_png*/ } // 下载完毕删除zip包资源 File zipFile = response.body(); if (zipFile != null && zipFile.exists()) { zipFile.delete(); } } @Override public void onError(Response<File> response) { Log.d(TAG, "onError: file_Download file出错,," + response + ",," + response.body() + ",," + response.message() + ",," + response.getException() + ",," + response.isSuccessful()); } @Override public void downloadProgress(Progress progress) { } }); } else { /*没有联网 下载出错 解析出错 都要初始化本地数据*/ } }
1)excute方法中,定义好下载后的资源存储处,下载成功监听中再处理;
2)onSuccess方法中,拿到下载好zip的资源存储处地址,然后调用解压缩的方法进行处理;
3)解压缩的方法中,输入参数为“需要解压缩文件所在地址”,输出的参数为“解压缩后得到的文件地址”;
解压缩方法如下:
public static String unZipDownlaodSvgToSdCard(Context context, String zipFileName) { String svgUnzipPath = ""; File zipFile = new File(zipFileName); Log.d(TAG, "unZipDownlaodToSdCard: 需要解压缩文件所在地址," + zipFile.getAbsolutePath()); String fileName = ""; File saveJsonFile = context.getExternalFilesDir("templatePng"); if (saveJsonFile != null) { fileName = saveJsonFile.getAbsolutePath(); } File file = new File(fileName); try { ZipUtils.unzipFile(zipFile, file); List<File> files = FileUtils.listFilesInDir(file); svgUnzipPath = files.get(0).getAbsolutePath(); Log.d(TAG, "unZipDownlaodToSdCard: 解压缩后得到的文件地址," + files.get(0).getAbsolutePath()); } catch (IOException e) { Log.e(TAG, "unZipDownlaodSvgToSdCard: " + e.getMessage() ); e.printStackTrace(); } return svgUnzipPath; }
5)下载一份放置Json文件的zip包;
下载解压缩部分如上,此外多加一步处理——解析下载好的Json文件:
private JsonParser parser = new JsonParser(); private static final String CATEGORY = "artphoto"; private static final String CONTENT = "classic"; private static final String VERSION = "version"; /*下载Json文件*/ private void onDownLoadAndSaveJson(String svgUrl, String fileName) { if (Utils.isNetWorkEnable(getActivity())) { OkGo.<File>get(svgUrl) .execute(new FileCallback(getActivity().getExternalFilesDir("templateJson").getAbsolutePath() + File.separator, fileName + ".zip") { @Override public void onSuccess(com.lzy.okgo.model.Response<File> response) { String zipFileName = getActivity().getExternalFilesDir("templateJson").getAbsolutePath() + File.separator + File.separator + fileName + ".zip"; String svgUnzipPath = ZipAndReadJsonUtils.unZipDownlaodSvgToSdCard(getActivity(), zipFileName); File f = response.body(); if (f != null && f.exists()) { String jsonPath = getActivity().getExternalFilesDir("templateJson").getAbsolutePath() + File.separator + "templates.json"; String jsonText = Utils.jsonTransformFromFile(jsonPath); JsonObject netRootObject = null; List<StyleEntity> entities = LitePal.select("name").find(StyleEntity.class); /*只查询name这一列 其他字段为null*/ List<String> entitieNames = new ArrayList<>(); for (int i = 0; i < entities.size(); i++) { entitieNames.add(entities.get(i).getNmae()); } try { netRootObject = (JsonObject) parser.parse(jsonText); JsonObject netCategoryObject = netRootObject.getAsJsonObject(CATEGORY); JsonArray netJsonArray = netCategoryObject.getAsJsonArray(CONTENT); String netVersion = netCategoryObject.getAsJsonPrimitive(VERSION).getAsString(); String localVersion = PreferenceManager.getDefaultSharedPreferences(getActivity()).getString("localVer", "0.0"); if (!localVersion.equals(netVersion)) { if (netJsonArray != null && netJsonArray.size() > 0) { PreferenceManager.getDefaultSharedPreferences(getActivity()).edit().putString("localVer", netVersion).apply(); for (int i = 0; i < netJsonArray.size(); i++) { JsonObject netObject = netJsonArray.get(i).getAsJsonObject(); String name = netObject.get("name").getAsString(); String index = netObject.get("index").getAsString(); String selected = netObject.get("selected").getAsString(); StyleEntity styleEntity = new StyleEntity(index, name, selected); if (!entitieNames.contains(name)) { styleEntity.save(); styleList.add(styleEntity); } } } } initAdapter(); } catch (JsonSyntaxException e) { Log.e(TAG, "onSuccess: 解析出错," + e.getMessage()); initAdapter(); } } } @Override public void onError(Response<File> response) { Log.d(TAG, "onError: file_Download file出错,," + response + ",," + response.body() + ",," + response.message() + ",," + response.getException() + ",," + response.isSuccessful()); initAdapter(); } @Override public void downloadProgress(Progress progress) { } }); } else { /*没有联网 下载出错 解析出错 都要初始化本地数据*/ initAdapter(); } }
①拿到解析后的Json文件地址,然后读取该地址的Json文件,得到String类型的数据源;
/*将存储在本地Json文件读取出来*/ public static String jsonTransformFromFile(String filePath) { File file = new File(filePath); StringBuilder stringBuilder = new StringBuilder(); try { FileInputStream fileInputStream = new FileInputStream(file); BufferedReader bf = new BufferedReader(new InputStreamReader(fileInputStream)); String line; while ((line = bf.readLine()) != null) { stringBuilder.append(line); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return stringBuilder.toString(); }
② 利用Gson库,将Json数据源按照字段,解析为一个个对象;
/** * Json格式为: * { * "artphoto": { * "version": "1.0", * "classic": [ * { * "name": "Forest Air", * "index": "http://120.55.58.174/artphoto/style30.jpg", * "selected": "false" * } * ] * } * } */ JsonObject netRootObject = null; netRootObject = (JsonObject) parser.parse(jsonText); JsonObject netCategoryObject = netRootObject.getAsJsonObject(CATEGORY); JsonArray netJsonArray = netCategoryObject.getAsJsonArray(CONTENT); String netVersion = netCategoryObject.getAsJsonPrimitive(VERSION).getAsString(); if (netJsonArray != null && netJsonArray.size() > 0) { for (int i = 0; i < netJsonArray.size(); i++) { JsonObject netObject = netJsonArray.get(i).getAsJsonObject(); String name = netObject.get("name").getAsString(); String index = netObject.get("index").getAsString(); String selected = netObject.get("selected").getAsString(); StyleEntity styleEntity = new StyleEntity(index, name, selected); if (!entitieNames.contains(name)) { styleEntity.save(); styleList.add(styleEntity); } } }
补充一个判断网络状态的工具类方法:
public static boolean isNetWorkEnable(Context context) { if (context != null) { ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = manager.getActiveNetworkInfo(); if (info != null) { return info.isAvailable(); } else { return false; } } return false; }
6)添加混淆;
#okhttp-dontwarn okhttp3.**-keep class okhttp3.**{*;}#okio-dontwarn okio.**-keep class okio.**{*;}# gson-keepattributes Signature-keepattributes *Annotation*-keep class sun.misc.Unsafe { *; }
结语:笔者OKGO用久了,顺手。不过现在有更高效的联网下载网络资源的方法,之后再更新。
发表评论
最新留言
哈哈,博客排版真的漂亮呢~
[***.90.31.176]2025年04月04日 18时12分22秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
375. Guess Number Higher or Lower II
2019-03-06
650. 2 Keys Keyboard
2019-03-06
764. Largest Plus Sign
2019-03-06
214. Shortest Palindrome
2019-03-06
916. Word Subsets
2019-03-06
869. Reordered Power of 2
2019-03-06
1086 Tree Traversals Again
2019-03-06
1127 ZigZagging on a Tree
2019-03-06
1062 Talent and Virtue
2019-03-06
1045 Favorite Color Stripe
2019-03-06
B. Spreadsheets(进制转换,数学)
2019-03-06
等和的分隔子集(DP)
2019-03-06
基础练习 十六进制转八进制(模拟)
2019-03-06
L - Large Division (大数, 同余)
2019-03-06
39. Combination Sum
2019-03-06
41. First Missing Positive
2019-03-06
80. Remove Duplicates from Sorted Array II
2019-03-06
83. Remove Duplicates from Sorted List
2019-03-06
410. Split Array Largest Sum
2019-03-06
开源项目在闲鱼、b 站上被倒卖?这是什么骚操作?
2019-03-06