实例:下载服务器zip资源(Json,Png,多种文件)

一、前期基础知识储备

1)OKGO库地址:https://github.com/jeasonlzy/okhttp-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用久了,顺手。不过现在有更高效的联网下载网络资源的方法,之后再更新。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值