OKhttp

public class OKHttp {

    private OkHttpClient client;
    private static volatile OKHttp instance;
    private Handler handler = new Handler();

    //创建拦截器
    private Interceptor getAppInterceptor(){
       Interceptor interceptor=new Interceptor() {
           @Override
           public Response intercept(Chain chain) throws IOException {
               Request request=chain.request();
               Log.e("+++++++","拦截前");
               Response response=chain.proceed(request);
               Log.e("+++++++","拦截后");
               return response;
           }
       };
        return interceptor;
    }
    //添加拦截器
    private OKHttp(){
        File file=new File(Environment.getExternalStorageDirectory(),"cach1");
        client = new OkHttpClient().newBuilder()
                .readTimeout(3000, TimeUnit.SECONDS)
                .connectTimeout(3000,TimeUnit.SECONDS)
                .addInterceptor(getAppInterceptor())
                .cache(new Cache(file,10*1024))
                .build();
    }
//创建单列
    public static OKHttp getInstance(){
        if (instance==null){
            synchronized (OKHttp.class){
                if (null==instance){
                    instance=new OKHttp();
                }
            }
}
        return instance;
    }
    //封装doget方法
    public void doGet(String url, final Class clazz, final NetCallBack netCallBack){
        //创建一个对象
        Request request=new Request.Builder()
                .get()
                .url(url)
                .build();
        //创建call对象
        Call call=client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String string = response.body().string();
                Gson gson = new Gson();
                final Object o = gson.fromJson(string, clazz);
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        netCallBack.LoadSuccess(o);
                    }
                });
            }
        });
    }
    //封装dopost请求
    public void doPost(String url, final Class clazz,String name,String pwd, final NetCallBack netCallBack)
    {
        //新建okhttp对象
        client = new OkHttpClient();
        /**
         * 通过体传值
         */
        FormBody build = new FormBody.Builder()
                .add("phone", name)
                .add("pwd", pwd)
                .build();
        Request request = new Request.Builder()
                .url(url)
                .post(build)
                .build();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String string = response.body().string();
                Gson gson = new Gson();
                final Object o = gson.fromJson(string, clazz);
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        netCallBack.LoadSuccess(o);
                    }
                });
            }
        });
    }



    public interface NetCallBack{
        void LoadSuccess(Object obj);
        void LoadFail();
    }
}

11-26
<think> 我们之前已经详细讨论过使用HTTP协议进行文件上传的方法,现在用户特别询问使用OkHttp库的实现方法。 根据引用[3],OkHttp在Android开发中是一个成熟且强大的网络库,甚至从Android 4.4开始HttpURLConnection的内部实现已经替换为OkHttp。 引用[2]和[4]提供了使用OkHttp的示例代码,引用[5]提到了在Android中使用OkHttp连接服务器时需要注意的安全配置(特别是HTTP明文传输的问题)。 因此,我们将重点放在使用OkHttp实现文件上传(用于更新文件)的方法上,并注意安全性和配置问题。 步骤: 1. 添加依赖 2. 创建OkHttpClient实例(可配置超时等) 3. 构建MultipartBody请求体,包含文件和其他参数 4. 创建请求对象,设置URL和请求方法(POST) 5. 发送请求(同步或异步) 6. 处理响应 同时,我们还需要考虑: - 进度监听 - 断点续传(需要服务器支持) - 安全传输(HTTPS、身份验证等) 引用[5]提到,如果使用HTTP明文传输,需要在AndroidManifest.xml中配置网络安全策略,允许明文传输(仅用于测试或内部环境,生产环境应使用HTTPS)。 下面给出详细实现: </think> 在安卓Java开发中,使用OkHttp实现文件更新与服务器通信的方法如下(结合引用内容优化): ### 一、基础实现步骤 1. **添加依赖** 在`build.gradle`中添加: ```gradle implementation 'com.squareup.okhttp3:okhttp:4.9.3' // 引用[2][4] ``` 2. **创建OkHttpClient实例** ```java OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) // 引用[4] .readTimeout(30, TimeUnit.SECONDS) .build(); ``` 3. **构建多部分请求体** ```java File file = new File("/sdcard/update.apk"); RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("file", file.getName(), RequestBody.create(file, MediaType.parse("application/octet-stream"))) .addFormDataPart("version", "2.0.1") // 附加参数 .build(); // 引用[3] ``` 4. **发送异步请求** ```java Request request = new Request.Builder() .url("https://your-server.com/update") .post(requestBody) .addHeader("Authorization", "Bearer token") // 安全验证 .build(); client.newCall(request).enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { if (response.isSuccessful()) { Log.i("UPLOAD", "更新成功: " + response.body().string()); } } @Override public void onFailure(Call call, IOException e) { Log.e("UPLOAD", "更新失败", e); } }); // 引用[2][4] ``` ### 二、关键优化方案 1. **进度监控实现** ```java class ProgressRequestBody extends RequestBody { private final File file; private final ProgressListener listener; @Override public void writeTo(BufferedSink sink) throws IOException { try (Source source = Okio.source(file)) { long total = file.length(); long uploaded = 0; Buffer buffer = new Buffer(); while (source.read(buffer, 2048) != -1) { sink.write(buffer, buffer.size()); uploaded += buffer.size(); listener.onProgress(uploaded, total); // 回调进度 buffer.clear(); } } } } ``` 2. **网络安全配置**(引用[5]) - 在`res/xml/network_security_config.xml`配置: ```xml <network-security-config> <base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config> </network-security-config> ``` - 在`AndroidManifest.xml`启用: ```xml <application android:networkSecurityConfig="@xml/network_security_config"> </application> ``` 3. **断点续传实现** ```java // 客户端 long uploadedBytes = getAlreadyUploadedSize(); // 从本地读取已上传量 request.addHeader("Range", "bytes=" + uploadedBytes + "-"); // 服务器端需支持Range请求处理 ``` ### 三、大文件处理建议 1. 分片上传(每片2-5MB): ```java int chunkSize = 5 * 1024 * 1024; // 5MB byte[] buffer = new byte[chunkSize]; try (InputStream in = new FileInputStream(file)) { int bytesRead; while ((bytesRead = in.read(buffer)) != -1) { RequestBody chunkBody = RequestBody.create(buffer, 0, bytesRead, MediaType.parse("application/octet-stream")); // 上传分片 } } ``` 2. 内存优化配置: ```java new OkHttpClient.Builder() .connectionPool(new ConnectionPool(5, 10, TimeUnit.MINUTES)) .cache(new Cache(context.getCacheDir(), 50 * 1024 * 1024)) // 50MB缓存 ``` ### 四、服务器响应处理 建议返回结构化数据(Spring Boot示例): ```java @PostMapping("/update") public ResponseEntity<Map<String, Object>> handleUpdate( @RequestParam("file") MultipartFile file) { Map<String, Object> response = new HashMap<>(); response.put("code", 200); response.put("newVersion", "2.1.0"); response.put("md5", DigestUtils.md5Hex(file.getBytes())); return ResponseEntity.ok(response); } ``` > **性能对比**:相比`HttpURLConnection`,OkHttp减少30%以上代码量,内置连接池复用TCP连接,提升传输效率(引用[3])。实测上传100MB文件时,OkHttp比HttpURLConnection快40%以上[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值