• 从0来搭建超灵活的MVP商用框架<二>-------APP基础配置、Okhttp+Retrofit封装


    在上一次https://www.cnblogs.com/webor2006/p/12445157.html中已经对于MVP的基础框架进行了搭建,但是呢该框架还少了很多东东,所以这次打算进一步完善一下,封装一个核心Module。

    App基础配置封装:

    框架搭建:

    新建一个核心Module,所以基础配置都放到这个下面:

     

    此时添加依赖关系:

    而由于app又依赖于isolation_processor层,所以也传递依赖于core。

    然后建一个包,对于APP的基础配置都放在其中:

    ConfigKeys:配置类型定义

    然后这里先为建立一个枚举类,里面标识着基本配置的类别,如下:

    package com.android.core.app;
    
    /**
     * 只是一个标识信息,这里的所有信息都是后面用来做KEY的
     */
    public enum ConfigKeys {
        API_HOST,
        APPLICATION_CONTEXT,
        INTERCEPTOR,
        //标识配置是否可用
        CONFIG_READY
    }

    有啥用?接着往下写就明白了,接下来则来建立一下配置类,里面则是具体配置存放获取的实现,如下:

    Configurator.java:APP配置写入和获取

    先将其定义为单例,这里采用枚举的方式来创建:

    接一来则来定义一些操作配置的方法,比较简单,直接贴出:

    package com.android.core.app;
    
    import java.util.HashMap;
    
    public class Configurator {
        private static final HashMap<Object, Object> CONFIGS = new HashMap<>();
    
        //单例:java并发实战中推的方法
        private static class Holder {
            private static final Configurator INSTANCE = new Configurator();
        }
    
        private Configurator() {
            CONFIGS.put(ConfigKeys.CONFIG_READY.name(), false);
        }
    
        public static Configurator getInstance() {
            return Holder.INSTANCE;
        }
    
        //获取配置信息
        final HashMap<Object, Object> getConfigs() {
            return CONFIGS;
        }
    
        //配置APIHOST
        public final Configurator withApiHost(String host) {
            CONFIGS.put(ConfigKeys.API_HOST, host);
            return this;
        }
    
        //配置完成
        public final void configure() {
            CONFIGS.put(ConfigKeys.CONFIG_READY.name(), true);
        }
    
        //检查配置是否完成
        private void checkConfiguration() {
            final boolean isReady = (boolean) CONFIGS.get(ConfigKeys.CONFIG_READY.name());
            if (!isReady) {
                throw new RuntimeException("Configuration is not ready,call configure()");
            }
        }
    
        final <T> T getConfiguration(Object key) {
            checkConfiguration();
            final Object value = CONFIGS.get(key);
            if (value == null) {
                throw new NullPointerException(key.toString() + "IS NULL");
            }
            return (T) value;
        }
    
    }

    其中这块用到了一个简单的建造者模式【当然不是标准的】可以链式的来调用,如下:

    ProjectInit.java:此类是开放给应用层来进行调用的。

    package com.android.core.app;
    
    import android.content.Context;
    
    /**
     * 这里就是给用户的API
     */
    public class ProjectInit {
        public static Configurator init(Context context) {
            Configurator.getInstance()
                    .getConfigs()
                    .put(ConfigKeys.APPLICATION_CONTEXT.name(), context.getApplicationContext());
            return Configurator.getInstance();
        }
    
        public static Configurator getConfigurator() {
            return Configurator.getInstance();
        }
    
        public static <T> T getConfiguration(Object key) {
            return getConfigurator().getConfiguration(key);
        }
    
        public static Context getApplicationContext() {
            return getConfiguration(ConfigKeys.APPLICATION_CONTEXT.name());
        }
    
    }

    对于上面的这个类中定义的方法貌似有点啰嗦,但是都是为了方便应用层来调用的,接下来咱们就可以来进行调用了,如下:

    Okhttp+Retrofit封装:

    接下来则来封装一下Okhttp+Retrofit网络请求功能,先来新建一个包,所有关于网络请求的都放其中:

    既然要用到Retrofit,则先添加相关的依赖:

    而OkHttp在上一次的隔离层已经添加了,但是由于隔离层是依赖于这个core模块的,所以这里将隔离层的OkHttp的依赖挪到这个core层上来:

     

    说到Retrofit,肯定得要先定义接口嘛,所以这里定义一下:

    RestService.java:定义网络请口

    package com.android.core.net;
    
    import java.util.Map;
    
    import okhttp3.MultipartBody;
    import okhttp3.RequestBody;
    import okhttp3.ResponseBody;
    import retrofit2.Call;
    import retrofit2.http.Body;
    import retrofit2.http.DELETE;
    import retrofit2.http.FieldMap;
    import retrofit2.http.FormUrlEncoded;
    import retrofit2.http.GET;
    import retrofit2.http.Multipart;
    import retrofit2.http.POST;
    import retrofit2.http.PUT;
    import retrofit2.http.Part;
    import retrofit2.http.QueryMap;
    import retrofit2.http.Streaming;
    import retrofit2.http.Url;
    
    public interface RestService {
        @GET
        Call<String> get(@Url String url, @QueryMap Map<String, Object> params);
    
        @FormUrlEncoded
        @POST
        Call<String> post(@Url String url, @FieldMap Map<String, Object> params);
    
        @FormUrlEncoded
        @PUT
        Call<String> put(@Url String url, @FieldMap Map<String, Object> params);
    
        @DELETE
        Call<String> delete(@Url String url, @QueryMap Map<String, Object> params);
    
        //下载是直接到内存,所以需要 @Streaming
        @Streaming
        @GET
        Call<ResponseBody> download(@Url String url, @QueryMap Map<String, Object> params);
    
        //上传
        @Multipart
        @POST
        Call<String> upload(@Url String url, @Part MultipartBody.Part file);
    
        //原始数据
        @POST
        Call<String> postRaw(@Url String url, @Body RequestBody body);
    
        @PUT
        Call<String> putRaw(@Url String url, @Body RequestBody body);
    }

    RestCreator.java:Retrofit对象封装

    这里可以看一下具体的写法,有一些技巧的,用静态内部类的方式来分层次的进行封装,既清晰又灵活,具体如下:

    package com.android.core.net;
    
    import com.android.core.app.ConfigKeys;
    import com.android.core.app.ProjectInit;
    
    import java.util.concurrent.TimeUnit;
    
    import okhttp3.OkHttpClient;
    import retrofit2.Retrofit;
    import retrofit2.converter.scalars.ScalarsConverterFactory;
    
    public final class RestCreator {
        /**
         * 产生一个全局的retrofit客户端
         */
        private static final class RetrofitHolder {
            private static final String BASE_URL = ProjectInit.getConfiguration(ConfigKeys.API_HOST);
            private static final Retrofit RETROFIT_CLIENT = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(ScalarsConverterFactory.create())
                    .client(OkHttpHolder.OK_HTTP_CLIENT)
                    .build();
        }
    
        /**
         * 可以单独设置的okhttp
         */
        private static final class OkHttpHolder {
            private static final int TIME_OUT = 60;
            private static final OkHttpClient OK_HTTP_CLIENT = new OkHttpClient.Builder()
                    .connectTimeout(TIME_OUT, TimeUnit.SECONDS)
                    .build();
        }
    
        //提供一个接口让调用者得到retrofit对象
        private static final class RestServiceHolder {
            private static final RestService REST_SERVICE = RetrofitHolder.RETROFIT_CLIENT
                    .create(RestService.class);
        }
    
        /**
         * 获取对象
         */
        public static RestService getRestService() {
            return RestServiceHolder.REST_SERVICE;
        }
    }

    RestClient:具体用户调用网络客户端的逻辑封装

    这里面的代码量稍稍大一点,但也是比较好理解的,所以不一一细说了,重点是掌握其封装方法,这里面先定义相关的一些字段:

    package com.android.core.net;
    
    import com.android.core.net.callback.IError;
    import com.android.core.net.callback.IFailure;
    import com.android.core.net.callback.IRequest;
    import com.android.core.net.callback.ISuccess;
    
    import java.io.File;
    import java.util.HashMap;
    
    import okhttp3.RequestBody;
    
    public class RestClient {
        private final HashMap<String, Object> PARAMS;
        private final String URL;
        private final IRequest REQUEST;
        private final ISuccess SUCCESS;
        private final IFailure FAILURE;
        private final IError ERROR;
        private final RequestBody BODY;
        //上传下载
        private final File FILE;
    
        private final String DOWNLOAD_DIR;
        private final String EXTENSION;
        private final String FILENAME;
    
        public RestClient(HashMap<String, Object> params,
                          String url,
                          IRequest request,
                          ISuccess success,
                          IFailure failure,
                          IError error,
                          RequestBody body,
                          File file, String downloadDir, String extension, String filename) {
            this.PARAMS = params;
            this.URL = url;
            this.REQUEST = request;
            this.SUCCESS = success;
            this.FAILURE = failure;
            this.ERROR = error;
            this.BODY = body;
    
            this.FILE = file;
            this.DOWNLOAD_DIR = downloadDir;  ///sdcard/XXXX.ext
            this.EXTENSION = extension;
            this.FILENAME = filename;
        }
    }

    其中有四个回调方法,所以定义一下:

    package com.android.core.net.callback;
    
    public interface IError {
        void onError(int code, String msg);
    }
    package com.android.core.net.callback;
    
    public interface IFailure {
        void onFailure();
    }
    package com.android.core.net.callback;
    
    public interface IRequest {
        void onRequestStart();
    
        void onRequestEnd();
    }
    package com.android.core.net.callback;
    
    public interface ISuccess {
        void onSuccess(String responce);
    }

    然后此时就可以再定义一个Okhttp的请求回调,将上面的各回调进行整合一下:

    package com.android.core.net.callback;
    
    import retrofit2.Call;
    import retrofit2.Callback;
    import retrofit2.Response;
    
    public class RequestCallbacks implements Callback<String> {
        private final IRequest REQUEST;
        private final ISuccess SUCCESS;
        private final IFailure FAILURE;
        private final IError ERROR;
    
        public RequestCallbacks(IRequest request, ISuccess success, IFailure failure, IError error) {
            this.REQUEST = request;
            this.SUCCESS = success;
            this.FAILURE = failure;
            this.ERROR = error;
        }
    
        @Override
        public void onResponse(Call<String> call, Response<String> response) {
            if (response.isSuccessful()) {
                if (call.isExecuted()) {
                    if (SUCCESS != null) {
                        SUCCESS.onSuccess(response.body());
                    }
                }
            } else {
                if (ERROR != null) {
                    ERROR.onError(response.code(), response.message());
                }
            }
        }
    
        @Override
        public void onFailure(Call<String> call, Throwable t) {
            if (FAILURE != null) {
                FAILURE.onFailure();
            }
            if (REQUEST != null) {
                REQUEST.onRequestEnd();
            }
        }
    }

    接下来则还是回到RestClient继续,既然它里面有这么多参数,要构建的话是不是用构建者模式相当合适,是的,所以下面来定义一下:

    package com.android.core.net;
    
    
    import com.android.core.net.callback.IError;
    import com.android.core.net.callback.IFailure;
    import com.android.core.net.callback.IRequest;
    import com.android.core.net.callback.ISuccess;
    
    import java.io.File;
    import java.util.HashMap;
    
    import okhttp3.MediaType;
    import okhttp3.RequestBody;
    
    public class RestClientBuilder {
        private HashMap<String, Object> mParams;
        private String mUrl;
        private IRequest mRequest;
        private ISuccess mSuccess;
        private IFailure mFailure;
        private IError mError;
        private RequestBody mBody;
    
        //上传下载
        private File mFile;
    
        private String mDownloadDir;
        private String mExtension;
        private String mFilename;
    
        RestClientBuilder() {
    
        }
    
        public final RestClientBuilder url(String url) {
            this.mUrl = url;
            return this;
        }
    
        public final RestClientBuilder params(HashMap<String, Object> params) {
            this.mParams = params;
            return this;
        }
    
        public final RestClientBuilder success(ISuccess success) {
            this.mSuccess = success;
            return this;
        }
    
        public final RestClientBuilder request(IRequest request) {
            this.mRequest = request;
            return this;
        }
    
        public final RestClientBuilder error(IError error) {
            this.mError = error;
            return this;
        }
    
        public final RestClientBuilder failure(IFailure failure) {
            this.mFailure = failure;
            return this;
        }
    
        public final RestClientBuilder raw(String raw) {
            this.mBody = RequestBody.create(
                    MediaType.parse("application/json;charset=UTF-8"), raw);
            return this;
        }
    
        //上传
        public final RestClientBuilder file(File file) {
            this.mFile = file;
            return this;
        }
    
        public final RestClientBuilder file(String file) {
            this.mFile = new File(file);
            return this;
        }
    
        //下载
        public final RestClientBuilder dir(String dir) {
            this.mDownloadDir = dir;
            return this;
        }
    
        public final RestClientBuilder extension(String extension) {
            this.mExtension = extension;
            return this;
        }
    
        public final RestClientBuilder filename(String filename) {
            this.mFilename = filename;
            return this;
        }
    
    
        public final RestClient build() {
            return new RestClient(mParams, mUrl, mRequest, mSuccess, mFailure, mError, mBody, mFile, mDownloadDir, mExtension, mFilename);
        }
    }

    接下来则需要封装一个真正请求的方法,具体代码也直接贴出来,比较好理解:

    package com.android.core.net;
    
    import com.android.core.net.callback.IError;
    import com.android.core.net.callback.IFailure;
    import com.android.core.net.callback.IRequest;
    import com.android.core.net.callback.ISuccess;
    import com.android.core.net.callback.RequestCallbacks;
    
    import java.io.File;
    import java.util.HashMap;
    
    import okhttp3.MultipartBody;
    import okhttp3.RequestBody;
    import retrofit2.Call;
    import retrofit2.Callback;
    
    public class RestClient {
        private final HashMap<String, Object> PARAMS;
        private final String URL;
        private final IRequest REQUEST;
        private final ISuccess SUCCESS;
        private final IFailure FAILURE;
        private final IError ERROR;
        private final RequestBody BODY;
        //上传下载
        private final File FILE;
    
        private final String DOWNLOAD_DIR;
        private final String EXTENSION;
        private final String FILENAME;
    
        public RestClient(HashMap<String, Object> params,
                          String url,
                          IRequest request,
                          ISuccess success,
                          IFailure failure,
                          IError error,
                          RequestBody body,
                          File file, String downloadDir, String extension, String filename) {
            this.PARAMS = params;
            this.URL = url;
            this.REQUEST = request;
            this.SUCCESS = success;
            this.FAILURE = failure;
            this.ERROR = error;
            this.BODY = body;
    
            this.FILE = file;
            this.DOWNLOAD_DIR = downloadDir;  ///sdcard/XXXX.ext
            this.EXTENSION = extension;
            this.FILENAME = filename;
        }
    
        public static RestClientBuilder create() {
            return new RestClientBuilder();
        }
    
        private Callback<String> getRequestCallback() {
            return new RequestCallbacks(REQUEST, SUCCESS, FAILURE, ERROR);
        }
    
        //开始真实的网络操作   参数HTTP_METHOD.GET  HTTP_METHOD.POST......
        private void request(HttpMethod method) {
            final RestService service = RestCreator.getRestService();
            Call<String> call = null;
            if (REQUEST != null) {
                REQUEST.onRequestStart();
            }
            //开始进行网络访问
            switch (method) {
                case GET:
                    call = service.get(URL, PARAMS);
                    break;
                case POST:
                    call = service.post(URL, PARAMS);
                    break;
                case PUT:
                    call = service.put(URL, PARAMS);
                    break;
                case DELETE:
                    call = service.delete(URL, PARAMS);
                    break;
                case UPLOAD:
             final RequestBody requestBody = RequestBody.create(MultipartBody.FROM, FILE);
                    final MultipartBody.Part body = MultipartBody.Part.createFormData(
                            "file", FILE.getName(), requestBody);
                    call = service.upload(URL, body);
                    break;
    
            }
            if (call != null) {
                call.enqueue(getRequestCallback());
            }
    
            if (REQUEST != null) {
                REQUEST.onRequestEnd();
            }
    
        }
    
        //各种请求(给用户使用的)
        //各种请求
        public final void get() {
            request(HttpMethod.GET);
        }
    
        public final void post() {
            request(HttpMethod.POST);
        }
    
        public final void put() {
            request(HttpMethod.PUT);
        }
    
        public final void delete() {
            request(HttpMethod.DELETE);
        }
    
        public final void upload() {
            request(HttpMethod.UPLOAD);
        }
    }

    其中HttpMethod是一个枚举:

    package com.android.core.net;
    
    enum HttpMethod {
        GET,
        POST,
        POST_RAW,
        PUT,
        PUT_RAW,
        DELETE,
        UPLOAD,
        DOWNLOAD
    }

    下载文件功能封装:

    接下来再增加网络下载功能,细节也不多说了,贴出代码:

    package com.android.core.download;
    
    import android.os.AsyncTask;
    
    import com.android.core.net.RestCreator;
    import com.android.core.net.callback.IError;
    import com.android.core.net.callback.IFailure;
    import com.android.core.net.callback.IRequest;
    import com.android.core.net.callback.ISuccess;
    
    import java.util.HashMap;
    
    import okhttp3.ResponseBody;
    import retrofit2.Call;
    import retrofit2.Callback;
    import retrofit2.Response;
    
    public class DownloadHandler {
        private final HashMap<String, Object> PARAMS;
        private final String URL;
        private final IRequest REQUEST;
        private final ISuccess SUCCESS;
        private final IFailure FAILURE;
        private final IError ERROR;
        private final String DOWNLOAD_DIR;
        private final String EXTENSION;
        private final String FILENAME;
    
        public DownloadHandler(HashMap<String, Object> params, String url,
                               IRequest request, ISuccess success,
                               IFailure failure, IError error,
                               String downloadDir, String extension, String filename) {
            this.PARAMS = params;
            this.URL = url;
            this.REQUEST = request;
            this.SUCCESS = success;
            this.FAILURE = failure;
            this.ERROR = error;
            this.DOWNLOAD_DIR = downloadDir;
            this.EXTENSION = extension;
            this.FILENAME = filename;
        }
    
        /**
         * 下载文件
         */
        public final void handleDownload() {
            RestCreator.getRestService().download(URL, PARAMS)
                    .enqueue(new Callback<ResponseBody>() {
                        @Override
                        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                            if (response.isSuccessful()) {
                                //开始把这次下载的结果保存到文件中,使用线程
                                SaveFileTask task = new SaveFileTask(REQUEST, SUCCESS);
                                task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
                                        DOWNLOAD_DIR, EXTENSION, response.body(), FILENAME);
                                //如果下载成功了,就告诉用户
                                if (task.isCancelled()) {
                                    if (REQUEST != null) {
                                        REQUEST.onRequestEnd();
                                    }
                                }
                            } else {
                                if (ERROR != null) {
                                    ERROR.onError(response.code(), response.message());
                                }
                            }
                        }
    
                        @Override
                        public void onFailure(Call<ResponseBody> call, Throwable t) {
                            FAILURE.onFailure();
                        }
                    });
        }
    
    }
    package com.android.core.download;
    
    import android.content.Intent;
    import android.net.Uri;
    import android.os.AsyncTask;
    
    import com.android.core.app.ProjectInit;
    import com.android.core.file.FileUtil;
    import com.android.core.net.callback.IRequest;
    import com.android.core.net.callback.ISuccess;
    
    import java.io.File;
    import java.io.InputStream;
    
    import okhttp3.ResponseBody;
    
    public class SaveFileTask extends AsyncTask<Object, Void, File> {
    
        private IRequest REQUEST;
        private ISuccess SUCCESS;
    
        public SaveFileTask(IRequest REQUEST, ISuccess SUCCESS) {
            this.REQUEST = REQUEST;
            this.SUCCESS = SUCCESS;
        }
    
        @Override
        protected File doInBackground(Object... params) {
    
            String downloadDir=(String)params[0];
            String extension=(String)params[1];
            ResponseBody body=(ResponseBody)params[2];
            String name=(String)params[3];
            InputStream is=body.byteStream();
            if(downloadDir==null || downloadDir.equals("")){
                downloadDir="downloads";
            }
            if(extension==null){
                extension="";
            }
            if(name==null){
                return FileUtil.writeToDisk(is,downloadDir,extension.toUpperCase(),extension);
            }else{
                return FileUtil.writeToDisk(is,downloadDir,name);
            }
        }
    
        //如果文件已经下完了
    
        @Override
        protected void onPostExecute(File file) {
            super.onPostExecute(file);
            if(SUCCESS!=null){
                SUCCESS.onSuccess(file.getPath());
            }
            if(REQUEST!=null){
                REQUEST.onRequestEnd();
            }
            //如果下了APK文件,就直接安装
            autoInstallApk(file);
        }
    
        private void autoInstallApk(File file) {
            if(FileUtil.getExtension(file.getPath()).equals("apk")){
                Intent intent=new Intent();
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.setAction(Intent.ACTION_VIEW);
                intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");
                ProjectInit.getApplicationContext().startActivity(intent);
            }
        }
    }
    package com.android.core.file;
    
    import android.os.Environment;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Locale;
    
    public class FileUtil {
        //格式化的模板
        private static final String TIME_FORMAT = "_yyyyMMdd_HHmmss";
    
        private static final String SDCARD_DIR =
                Environment.getExternalStorageDirectory().getPath();
    
        private static String getTimeFormatName(String timeFormatHeader) {
            final Date date = new Date(System.currentTimeMillis());
            //必须要加上单引号
            final SimpleDateFormat dateFormat = new SimpleDateFormat("'" + timeFormatHeader + "'" + TIME_FORMAT, Locale.getDefault());
            return dateFormat.format(date);
        }
    
        /**
         * @param timeFormatHeader 格式化的头(除去时间部分)
         * @param extension        后缀名
         * @return 返回时间格式化后的文件名
         */
        public static String getFileNameByTime(String timeFormatHeader, String extension) {
            return getTimeFormatName(timeFormatHeader) + "." + extension;
        }
    
        @SuppressWarnings("ResultOfMethodCallIgnored")
        private static File createDir(String sdcardDirName) {
            //拼接成SD卡中完整的dir
            final String dir = SDCARD_DIR + "/" + sdcardDirName + "/";
            final File fileDir = new File(dir);
            if (!fileDir.exists()) {
                fileDir.mkdirs();
            }
            return fileDir;
        }
    
        @SuppressWarnings("ResultOfMethodCallIgnored")
        public static File createFile(String sdcardDirName, String fileName) {
            return new File(createDir(sdcardDirName), fileName);
        }
    
        private static File createFileByTime(String sdcardDirName, String timeFormatHeader, String extension) {
            final String fileName = getFileNameByTime(timeFormatHeader, extension);
            return createFile(sdcardDirName, fileName);
        }
    
    
        //获取文件的后缀名
        public static String getExtension(String filePath) {
            String suffix = "";
            final File file = new File(filePath);
            final String name = file.getName();
            final int idx = name.lastIndexOf('.');
            if (idx > 0) {
                suffix = name.substring(idx + 1);
            }
            return suffix;
        }
    
        public static File writeToDisk(InputStream is, String dir, String name) {
            final File file = FileUtil.createFile(dir, name);
            BufferedInputStream bis = null;
            FileOutputStream fos = null;
            BufferedOutputStream bos = null;
    
            try {
                bis = new BufferedInputStream(is);
                fos = new FileOutputStream(file);
                bos = new BufferedOutputStream(fos);
    
                byte data[] = new byte[1024 * 4];
    
                int count;
                while ((count = bis.read(data)) != -1) {
                    bos.write(data, 0, count);
                }
    
                bos.flush();
                fos.flush();
    
    
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bos != null) {
                        bos.close();
                    }
                    if (fos != null) {
                        fos.close();
                    }
                    if (bis != null) {
                        bis.close();
                    }
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            return file;
        }
    
        public static File writeToDisk(InputStream is, String dir, String prefix, String extension) {
            final File file = FileUtil.createFileByTime(dir, prefix, extension);
            BufferedInputStream bis = null;
            FileOutputStream fos = null;
            BufferedOutputStream bos = null;
    
            try {
                bis = new BufferedInputStream(is);
                fos = new FileOutputStream(file);
                bos = new BufferedOutputStream(fos);
    
                byte data[] = new byte[1024 * 4];
    
                int count;
                while ((count = bis.read(data)) != -1) {
                    bos.write(data, 0, count);
                }
    
                bos.flush();
                fos.flush();
    
    
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bos != null) {
                        bos.close();
                    }
                    if (fos != null) {
                        fos.close();
                    }
                    if (bis != null) {
                        bis.close();
                    }
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            return file;
        }
    }

    应用:

    目前网络层已经用Okhttp+Retrofit进行改造完了,对于之前隔离层中就可以增加一个Retrofit的网络访问方式,如下:

    package com.android.isolation_processor.httpprocessor;
    
    import android.util.Log;
    
    import com.android.core.net.RestClient;
    import com.android.core.net.callback.IFailure;
    import com.android.core.net.callback.ISuccess;
    
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;
    
    public class RetrofitProcessor implements IHttpProcessor {
        @Override
        public void post(String url, Map<String, Object> params, ICallback callback) {
            //在这里用已经写好的代码来访问网络
            HashMap param = new HashMap();
            Set<String> keySet = params.keySet();
            Iterator<String> keys = keySet.iterator();
            while (keys.hasNext()) {
                String key = (String) keys.next();
                Object value = params.get(key);
                param.put(key, value);
            }
    
            RestClient.create()
                    .url(url)
                    .params(param)
                    .success(new ISuccess() {
                        @Override
                        public void onSuccess(String responce) {
                            Log.i("cexo", "retrofit=" + responce);
                        }
                    })
                    .failure(new IFailure() {
                        @Override
                        public void onFailure() {
    
                        }
                    })
                    .build()
                    .get();
        }
    }

    其运行结果:

    另外对于上传下载这块的调用这里贴出来一个模拟的,就不来验证下载成功与否了:

    关于整个框架其实还有待改进的,这块在下一次继续完善,其中Dagger2在之前已经学习过了会将其应用进这个框架中。

  • 相关阅读:
    Vijos / 题库 / 输油管道问题
    军事机密(Secret.pas)
    1164 统计数字
    1142 奖学金 sort做法
    1487 大批整数排序
    1487 大批整数排序
    1545 最简单排序
    1470 数列处理
    1683 车厢重组
    spin.js无图片实现loading进度条,支持但非依赖jquery
  • 原文地址:https://www.cnblogs.com/webor2006/p/12455238.html
Copyright © 2020-2023  润新知