实例:下载服务器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用久了,顺手。不过现在有更高效的联网下载网络资源的方法,之后再更新。

 

 

上一篇:实例:Android中运用反射机制
下一篇:实例:应用谷歌最新开屏广告

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2025年04月04日 18时12分22秒