Android开发okhttp+retrofit+rxJava 之文件上传下载

35 篇文章 1 订阅

基于上一篇文章实现了基本的okhttp请求基本用法: https://mp.csdn.net/editor/html/115055910

下面结合retrofit和rxJava实现文件上传下载, 带下载进度,.

基本介绍

. Retrofit是基于okhttp基础上进行高度封装或者包装的产物, 结合rxJava, 可以说是如鱼得水,天作之合, 可以很方便实现网络请求的同步异步切换, 摆脱了以前的AsyncTask和Handler机制. 直接链式写法实现网络切换;

1. 基本实现  retrofit的封装类:

package com.hulk.android.http.retrofit;

import android.text.TextUtils;
import android.util.Log;

import com.hulk.android.http.ok.OkHttpManager;
import com.hulk.android.http.ok.ProgressListener;

import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Retrofit 管理器
 * @author: zhanghao
 * @Time: 2021-03-04 16:00
 */
public class RetrofitManager {
    private static final String TAG = "RetrofitManager";

    Retrofit mRetrofit;
    String mBaseUrl;

    /**
     * 浏览器模式,此模式 Ok http client 下不执行SSL证书等等验证,直接下载
     */
    boolean browserMode = true;

    /**
     * 全局精度监听器, 与 OK http 绑定
     */
    ProgressListener mProgressListener;

    static RetrofitManager instance = new RetrofitManager();

    public static RetrofitManager getInstance() {
        return instance;
    }

    private RetrofitManager() {
    }

    public void setProgressListener(ProgressListener progressListener) {
        this.mProgressListener = progressListener;
    }

    public void setBrowserMode(boolean browserMode) {
        this.browserMode = browserMode;
    }

    public void setBaseUrl(String baseUrl) {
        this.mBaseUrl = baseUrl;
    }

    public String getBaseUrl() {
        return mBaseUrl;
    }

    public OkHttpClient getOkHttpClient() {
        return getOkHttpClient(mProgressListener);
    }

    public OkHttpClient getOkHttpClient(ProgressListener listener) {
        if (listener == null) {
            Log.w(TAG, "getOkHttpClient: progress listener is null");
        }
        if (browserMode) {
            return OkHttpManager.getBrowserDownloadClient(listener);
        }
        return OkHttpManager.getDownloadSslClient(listener);
    }

    public Retrofit getRetrofit() {
        ensureRetrofit();
        return mRetrofit;
    }

    public static Retrofit createRetrofit(String baseUrl, OkHttpClient okHttpClient) {
        //可以增加其他转换器
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(okHttpClient)
                .addConverterFactory(ToByteConvertFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
        return retrofit;
    }

    public Retrofit createRetrofit(OkHttpClient okHttpClient) {
        String baseUrl = getAvailableBaseUrl();
        return createRetrofit(baseUrl, okHttpClient);
    }

    public String getAvailableBaseUrl() {
        if (TextUtils.isEmpty(mBaseUrl)) {
            mBaseUrl = "https://www.baidu.com";
        }
        return mBaseUrl;
    }

    private void initRetrofit() {
        initRetrofit(getOkHttpClient());
    }

    public void initRetrofit(OkHttpClient okHttpClient) {
        mRetrofit = createRetrofit(okHttpClient);
    }

    private void initRetrofit(ProgressListener progressListener) {
        initRetrofit(getOkHttpClient(progressListener));
    }

    private void ensureRetrofit() {
        if (mRetrofit == null) {
            initRetrofit();
        }
    }
}

2. Retrofit 中的API定义

下载API

/**
 * 下载API
 * @author: zhanghao
 * @Time: 2021-02-25 21:29
 */
public interface DownloadApiService {
    /**
     * 下载通用函数
     * @param url
     * @return
     */
    @Streaming
    @GET
    Observable<ResponseBody> download(@Url String url);
}
package com.hulk.android.http.upload;

import com.hulk.android.http.conn.HttpResult;

import java.util.Map;

import io.reactivex.Observable;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.http.Body;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.PartMap;
import retrofit2.http.Url;

/**
 * 上传文件接口
 * @author: zhanghao
 * @Time: 2021-02-26 10:41
 */
public interface UploadApiService {

    /**
     * 上传单个文本和单个文件
     * @param textBody 文本数据: text 字段名称, 实际开发中在确定.
     * @param fileBody  文件数据: file 为字段名称, test.png 为服务器上保存的文件名, 实际开发中在确定,
     * @return
     */
    @Multipart
    @POST("v1/uploadImg")
    Observable<HttpResult> uploadImg(@Part("text") RequestBody textBody, @Part("file\"; filename=\"test.png") RequestBody fileBody);

    /**
     * 上传多个文本和多个文件(传递map)
     * @param textBodyMap 文本map
     * @param fileBodyMap  文件map
     * @return
     */
    @Multipart
    @POST("v1/uploadFiles")
    Observable<HttpResult> upLoad(@PartMap Map<String, RequestBody> textBodyMap, @PartMap Map<String, RequestBody> fileBodyMap);

    /**
     * 上传多个文本和多个文件, 传递 MultipartBody:
     * MultipartBody.Builder builder = new MultipartBody.Builder();
     * //文本部分
     * builder.addFormDataPart("title", "User comments");
     * builder.addFormDataPart("content", "The retrofit+Rxjava is perfect");
     *
     * //文件部分
     * File file1 = new File("hulk.jpg");
     * RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpg"), file1);
     * // “image”为文件参数的参数名
     * builder.addFormDataPart("image", file1.getName(), requestBody);
     *
     * File file2 = new File("hulk.mp4");
     * RequestBody requestBody2 = RequestBody.create(MediaType.parse("video/mp4"), file2);
     * // “video”为文件参数的参数名
     * builder.addFormDataPart("video", file2.getName(), requestBody2);
     *
     * builder.setType(MultipartBody.FORM);
     * MultipartBody multipartBody = builder.build();
     *
     * @param url  直接使用完整的 url
     * @param multipartBody
     * @return
     */
    @POST
    Observable<HttpResult> upLoad(@Url String url, @Body MultipartBody multipartBody);
}

3. 下载器

RetrofitDownloader

package com.hulk.android.http.download;

import android.content.Context;
import android.os.Environment;
import android.text.TextUtils;

import com.hulk.android.http.content.FileHelper;
import com.hulk.android.log.Log;


import com.hulk.android.http.utils.HttpFileUtils;
import com.hulk.android.http.ok.OkHttpManager;
import com.hulk.android.http.ok.ProgressListener;
import com.hulk.android.http.retrofit.RetrofitManager;

import java.io.InputStream;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import retrofit2.Retrofit;

/**
 * retrofit下载器
 * @author: zhanghao
 * @Time: 2021-02-25 21:06
 */
public class RetrofitDownloader {
    private static final String TAG = "RetrofitDownloader";

    Context context;
    String baseUrl;

    Retrofit retrofit;
    DownloadApiService downloadService;
    /**
     * 浏览器模式,此模式 Ok http client 下不执行SSL证书等等验证,直接下载
     */
    boolean browserMode = true;
    long contentLength = 0;

    /**
     * 全局精度监听器
     */
    ProgressListener mProgressListener;

    public RetrofitDownloader(Context context) {
        this.context = context;
        init();
    }

    public RetrofitDownloader(Context context, ProgressListener progressListener) {
        this.context = context;
        this.mProgressListener = progressListener;
        init();
    }

    public RetrofitDownloader(Context context, String baseUrl, boolean browserMode, ProgressListener progressListener) {
        this.context = context;
        this.baseUrl = baseUrl;
        this.browserMode = browserMode;
        this.mProgressListener = progressListener;
        init();
    }

    public RetrofitDownloader(Context context, Retrofit retrofit) {
        this.context = context;
        this.retrofit = retrofit;
    }

    private OkHttpClient getOkHttpClient() {
        return getOkHttpClient(mProgressListener);
    }

    private OkHttpClient getOkHttpClient(ProgressListener listener) {
        if (listener == null) {
            Log.w(TAG, "getOkHttpClient: progress listener is null");
        }
        if (browserMode) {
            return OkHttpManager.getBrowserDownloadClient(listener);
        }
        return OkHttpManager.getDownloadSslClient(listener);
    }

    public void init(OkHttpClient okHttpClient) {
        downloadService = createDownloadApiService(okHttpClient);
    }

    public DownloadApiService createDownloadApiService(OkHttpClient client) {
        String baseUrl = getAvailableBaseUrl();
        return RetrofitManager.createRetrofit(baseUrl, client).create(DownloadApiService.class);
    }

    public String getAvailableBaseUrl() {
        if (TextUtils.isEmpty(baseUrl)) {
            //baseUrl = ByodApiManager.getBaseUrl(context);
            baseUrl = "https://www.baidu.com";
        }
        return baseUrl;
    }

    private void init() {
        init(getOkHttpClient());
    }

    private void init(ProgressListener progressListener) {
        init(getOkHttpClient(progressListener));
    }

    private void ensureRetrofit() {
        if (retrofit == null) {
            init();
        }
    }

    /**
     * 下载
     * <p>使用observer实现精度结果监听,更为常用先进
     * @param url
     * @param filePath
     * @param observer
     */
    public void download(@NonNull String url, final String filePath, final DownloadObserver observer) {
        Log.i(TAG, "download2: url=" + url + ", filePath=" + filePath + ", observer=" + observer);
        //通过Observable发起请求
        ensureRetrofit();
        Observable<ResponseBody> observable = downloadService.download(url);
        observable
                //指定网络请求在io后台线程中进行
                .subscribeOn(Schedulers.io())
                //指定doOnNext的操作在io后台线程进行
                .observeOn(Schedulers.io())
                .doOnNext(new Consumer<ResponseBody>() {
                    //doOnNext里的方法执行完毕,observer里的onNext、onError等方法才会执行。
                    @Override
                    public void accept(ResponseBody body) throws Exception {
                        //下载文件,通过body.byteStream()可以得到输入流, 保存到本地
                        InputStream inputStream = body.byteStream();
                        long contentLength = body.contentLength();
                        Log.i(TAG, "doOnNext.accept contentLength: " + contentLength);
                        FileDownloadImpl impl = new FileDownloadImpl(url, filePath, contentLength, observer.downloadListener);
                        FileHelper.writeDownloadFile(inputStream, filePath, impl);
                    }
                })
                //指定observer回调在UI主线程中进行
                .observeOn(AndroidSchedulers.mainThread())
                //发起请求,请求的结果先回调到doOnNext进行处理,再回调到observer中
                .subscribe(observer);
    }

    public void download(@NonNull String url, final String filePath, final DownloadListener downloadListener) {
        Log.i(TAG, "download2: url=" + url + ", filePath=" + filePath);
        download(url, filePath, new DownloadObserver(url, filePath, downloadListener));
    }

    public static void test(Context context, String url) {
        DownloadListener downloadListener = new DownloadListener() {
            @Override
            public void onStart(String remark) {
                Log.w(TAG, "DownloadListener.onStart: " + remark);
            }

            @Override
            public void onProgress(int progress) {
                Log.w(TAG, "DownloadListener.onProgress: " + progress);
            }

            @Override
            public void onFinished(String url, String filePath) {
                Log.w(TAG, "DownloadListener.onFinished: " + url + ", filePath=" + filePath);
            }

            @Override
            public void onFailure(Throwable throwable) {
                Log.e(TAG, "onFailure: " + throwable);
            }
        };
        RetrofitDownloader downloader = new RetrofitDownloader(context);
        String filename = HttpFileUtils.getFileName(url);
        String filePath = Environment.getExternalStorageDirectory() + "/Hulk/file/" + filename;
        downloader.download(url, filePath, downloadListener);
    }

    public static void test(Context context) {
        String url = "https://s.shouji.qihucdn.com/210307/1fa2b07cdca7a7f81f8c4eedff06499b/com.qihoo.appstore_300090095.apk?en=curpage%3D%26exp%3D1615781273%26from%3Dopenbox_channel_getUrl%26m2%3D%26ts%3D1615176473%26tok%3D30feb64608edefe4b78cbabe4a91d6f5%26v%3D%26f%3Dz.apk";
        test(context, url);
    }
}

4. 实现网络图片异步加载公用类:

package com.hulk.android.http.image;

import android.content.Context;
import android.graphics.Bitmap;
import android.text.TextUtils;
import android.util.Log;
import android.util.LruCache;
import android.widget.ImageView;

import com.hulk.android.http.download.DownloadListener;
import com.hulk.android.http.download.DownloadUtil;
import com.hulk.android.http.download.RetrofitDownloader;

/**
 * 图片加载器
 * @author: zhanghao
 * @Time: 2021-03-04 20:09
 */
public class ImageLoader {
    private static final String TAG = "ImageLoader";

    private static class ImageLoaderHolder {
        private static ImageLoader imageLoader = new ImageLoader();

        public static ImageLoader get() {
            return imageLoader;
        }
    }

    private Context mContext = null;
    private LruCache<String, Bitmap> mCache = ImageLoadHelper.sCache;
    private ImageView mImageView;
    private String mUrl = null;
    private String mCacheFileName = null;
    private ImageLoadCallback mCallback = null;
    private int defaultImgResId = 0;
    private int errorImgResId = 0;
    private boolean needDownload = true;

    private RetrofitDownloader mDownloader;
    private String mFilename;

    private ImageLoader() {
    }

    public static ImageLoader with(Context context) {
        ImageLoader loader = ImageLoaderHolder.get();
        loader.init(context);
        return loader;
    }

    private void init(Context context) {
        this.mContext = context;
    }

    public ImageLoader load(String url) {
        this.mUrl = url;
        return this;
    }

    public ImageLoader filePath(String filename) {
        this.mFilename = filename;
        return this;
    }

    public ImageLoader defaultImgResId(int defaultImgResId) {
        this.defaultImgResId = defaultImgResId;
        return this;
    }

    public ImageLoader errorImgResId(int errorImgResId) {
        this.errorImgResId = errorImgResId;
        return this;
    }

    public ImageLoader callback(ImageLoadCallback callback) {
        this.mCallback = callback;
        return this;
    }

    public ImageLoader cache(LruCache<String, Bitmap> cache) {
        this.mCache = cache;
        return this;
    }

    private ImageLoader needDownload(boolean needDownload) {
        this.needDownload = needDownload;
        return this;
    }

    public void into(ImageView imageView) {
        this.mImageView = imageView;
        boolean preloaded = preload();
        if (preloaded) {
            //Log.w(TAG, "into: preloaded.");
            return;
        }
        //download();
        download2();
    }

    private boolean canDownload() {
        if (!needDownload) {
            Log.w(TAG, "canDownload: Not need download.");
            return false;
        }
        if (isDownloading()) {
            Log.i(TAG, "canDownload: Downloading: " + mUrl);
            return false;
        }
        return true;
    }

    private void download() {
        if (!canDownload()) {
            Log.w(TAG, "download: Can not download.");
            return;
        }
        ImageLoadHelper.ensureCacheDir();
        String filePath = getFilePath();
        Log.i(TAG, "download: mUrl=" + mUrl + ", filePath=" + filePath);
        DownloadUtil.download(mUrl, filePath, new DownloadImpl());
    }

    private void download2() {
        if (!canDownload()) {
            Log.w(TAG, "download2: Not need download.");
            return;
        }
        if (mDownloader == null) {
            mDownloader = new RetrofitDownloader(mContext);
        }
        ImageLoadHelper.ensureCacheDir();
        String filePath = getFilePath();
        Log.i(TAG, "download2: mUrl=" + mUrl + ", filePath=" + filePath);
        mDownloader.download(mUrl, filePath, new DownloadImpl());
    }

    private boolean preload() {
        String url = mUrl;
        if (TextUtils.isEmpty(url)){
            // 设置为默认图片
            Log.w(TAG, "preload: set default Image for url is empty.");
            setImageResource(errorImgResId);
            onImageLoadFailed();
            return true;
        }

        // 先从缓存中查找
        Bitmap img = getCache(url);
        if (img != null) {
            setImageBitmap(img);
            return true;
        }

        Bitmap bp = getImageFromLocal();
        if (bp != null) {
            setImageBitmap(bp);
            putCache(mUrl, bp);
            return true;
        }
        // 先设置为默认图片
        setImageResource(defaultImgResId);
        return false;
    }

    private void postDownLoad(String url, String filePath) {
        if (mImageView == null) {
            Log.i(TAG, "postDownLoad: mImageView is null");
            return;
        }
        Object tag = mImageView.getTag();
        if (tag instanceof String) {
            url = (String) tag;
        }
        Bitmap image = getLocalImage(filePath);
        if (image == null) {
            // 设置为默认图片
            Log.w(TAG, "onPostExecute: set default image for result is null");
            setImageResource(errorImgResId);
            onImageLoadFailed();
        } else {
            putCache(url, image);
            setImageBitmap( image);
        }
    }

    private void putCache(String url, Bitmap image) {
        if (TextUtils.isEmpty(url) || image == null) {
            return;
        }
        if (mCache != null) {
            mCache.put(url, image);
        }
    }

    private Bitmap getCache(String url) {
        if (TextUtils.isEmpty(url)) {
            return null;
        }
        if (mCache == null) {
            return null;
        }
        Bitmap image = mCache.get(url);
        return image;
    }

    private void setImageBitmap(Bitmap bitmap) {
        if (bitmap != null && mImageView != null) {
            mImageView.setImageBitmap(bitmap);
        }
        onImageLoadSuccess(bitmap);
    }

    private void setImageResource(int resId) {
        if (resId > 0 && mImageView != null) {
            mImageView.setImageResource(resId);
        }
    }

    private void onImageLoadSuccess(Bitmap bitmap) {
        if (mCallback != null){
            mCallback.onImageLoadSuccess(mUrl, mImageView, bitmap);
        }
    }

    private void onImageLoadFailed() {
        if (mCallback != null){
            mCallback.onImageLoadFailed(mUrl, mImageView);
        }
    }

    private boolean isDownloading() {
        return ImageLoadHelper.checkDownloading(mUrl);
    }

    private void removeDownloading() {
        ImageLoadHelper.removeDownloading(mUrl);
    }

    private Bitmap getImageFromLocal() {
        String filename = getFilename();
        return ImageLoadHelper.getImageFromLocal(filename);
    }

    private Bitmap getLocalImage(String filePath) {
        return ImageLoadHelper.getLocalImage(filePath);
    }

    private String getFilename() {
        if (TextUtils.isEmpty(mFilename)) {
            mFilename = ImageLoadHelper.getFileName(mUrl);
        }
        return mFilename;
    }

    private String getFilePath() {
        String filename = getFilename();
        return ImageLoadHelper.getCacheFilePath(filename);
    }

    private class DownloadImpl implements DownloadListener {
        @Override
        public void onStart(String remark) {
            Log.w(TAG, "onStart: " + remark);
        }

        @Override
        public void onProgress(int progress) {
            Log.v(TAG, "onProgress: " + progress);
        }

        @Override
        public void onFinished(String url, String filePath) {
            Log.w(TAG, "onFinished: " + url + ",filePath: " + filePath);
            postDownLoad(url, filePath);
        }

        @Override
        public void onFailure(Throwable throwable) {
            Log.e(TAG, "onFailure: " + throwable);
            setImageResource(errorImgResId);
        }
    }
}

6. Activity中基本用法

package com.android.hulk.androidutils;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.hulk.android.http.download.DownloadListener;
import com.hulk.android.http.download.RetrofitDownloader;
import com.hulk.android.http.image.ImageLoadCallback;
import com.hulk.android.http.image.ImageLoadHelper;
import com.hulk.android.http.utils.HttpFileUtils;
import com.hulk.android.log.Log;
import com.hulk.android.log.RuntimeLog;
import com.hulk.util.file.PrintUtil;

import java.util.Arrays;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    private static final String WRITE_EXTERNAL_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE;
    private static final String READ_EXTERNAL_STORAGE = Manifest.permission.READ_EXTERNAL_STORAGE;
    private static final String[] PERMISSIONS = {WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE};

    private static final String IMAGE_URL = "https://pics5.baidu.com/feed/b8389b504fc2d56263ab63951219b5e776c66c3c.jpeg?token=e3f2b3a4806bb1a38913457e6ecb160a&s=1ECF985E4CDD0CC80687F3F10300801E";
    private static final String IMAGE_URL2 = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa3.att.hudong.com%2F65%2F38%2F16300534049378135355388981738.jpg&refer=http%3A%2F%2Fa3.att.hudong.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1617537464&t=f6e8544f19d6eb754aaa057f125e4373";
    private static final String IMAGE_URL3 = "https://gss0.baidu.com/70cFfyinKgQFm2e88IuM_a/forum/w%3d580/sign=9cdd7204e51190ef01fb92d7fe199df7/b13533fa828ba61eb13b6ac64334970a314e5905.jpg";

    Context mContext;
    ImageView img_view;
    TextView msg_tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = getApplicationContext();
        setContentView(R.layout.activity_main2);
        Log.w(TAG, "onCreate: ");
        requestPermissionsIfNot();

        img_view = findViewById(R.id.img_view);
        msg_tv = findViewById(R.id.msg_tv);

        Button download_file_view = findViewById(R.id.download_file_view);
        if (download_file_view != null) {
            download_file_view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    test(mContext);
                }
            });
        }
        testLoadImage();
    }

    private void testLoadImage() {
        Button load_glide_view = findViewById(R.id.load_glide_view);
        if (load_glide_view != null) {
            load_glide_view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ImageLoadHelper.loadByGlide(mContext, img_view, IMAGE_URL, R.mipmap.app_default_icon);
                }
            });
        }

        Button load_task_view = findViewById(R.id.load_task_view);
        if (load_task_view != null) {
            load_task_view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ImageLoadHelper.loadByTask(mContext, img_view, IMAGE_URL2, R.mipmap.app_default_icon);
                }
            });
        }

        Button load_image_view = findViewById(R.id.load_image_view);
        if (load_image_view != null) {
            load_image_view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ImageLoadHelper.loadImage(mContext, img_view, IMAGE_URL3, R.mipmap.app_default_icon, new ImageLoadCallback() {
                        @Override
                        public void onImageLoadSuccess(String url, ImageView view, Bitmap bitmap) {
                            Log.w(TAG, "onImageLoadSuccess: " + view + ", bitmap=" + bitmap);
                        }

                        @Override
                        public void onImageLoadFailed(String url, ImageView view) {
                            Log.w(TAG, "onImageLoadSuccess: " + view);
                        }
                    });
                }
            });
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.w(TAG, "onStart: ");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.w(TAG, "onResume: ");
        RuntimeLog.flushAsync(TAG + ".onResume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.w(TAG, "onPause: ");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.w(TAG, "onStop: ");
    }

    @Override
    protected void onDestroy() {
        Log.w(TAG, "onDestroy: ");
        RuntimeLog.flushAsync(TAG + ".onDestroy");
        super.onDestroy();
    }

    protected void requestPermissionsIfNot() {
        if (Build.VERSION.SDK_INT >= 23) {
            if (checkSelfPermission(WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                Log.w(TAG, "requestPermissions: " + Arrays.toString(PERMISSIONS));
                requestPermissions(PERMISSIONS, 1);
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        Log.w(TAG, "onRequestPermissionsResult: requestCode=" + requestCode
                + ", permissions=" + Arrays.toString(permissions) + ", grantResults= " + grantResults);
    }

    protected void setMsg(String text, boolean append) {
        if (append) {
            msg_tv.append("\n" + text);
        } else {
            msg_tv.setText(text);
        }
    }

    protected void setMsg(String text) {
        setMsg(text, false);
    }

    protected void appendMsg(String text) {
        setMsg(text, true);
    }

    public void test(Context context, String url) {
        msg_tv.setTextColor(Color.BLACK);
        setMsg("Downloading from url: " + url);
        DownloadListener downloadListener = new DownloadListener() {
            @Override
            public void onStart(String remark) {
                Log.w(TAG, "DownloadListener.onStart: " + remark);
                appendMsg("onStart: " + remark);
            }

            @Override
            public void onProgress(int progress) {
                Log.w(TAG, "DownloadListener.onProgress: " + progress);
                appendMsg("onProgress: " + progress);
            }

            @Override
            public void onFinished(String url, String filePath) {
                Log.w(TAG, "DownloadListener.onFinished: " + url + ", filePath=" + filePath);
                msg_tv.append("onFinished: " + filePath);
            }

            @Override
            public void onFailure(Throwable throwable) {
                Log.e(TAG, "onFailure: " + throwable);
                msg_tv.setTextColor(Color.RED);
                appendMsg("onFailure: " + throwable + "\n" + PrintUtil.formatStackTrace("", throwable));
            }
        };
        RetrofitDownloader downloader = new RetrofitDownloader(context);
        String filename = "test.apk";
        String filePath = Environment.getExternalStorageDirectory() + "/Hulk/file/" + filename;
        downloader.download(url, filePath, downloadListener);
    }

    public void test(Context context) {
        String url = "https://s.shouji.qihucdn.com/210307/1fa2b07cdca7a7f81f8c4eedff06499b/com.qihoo.appstore_300090095.apk?en=curpage%3D%26exp%3D1615781273%26from%3Dopenbox_channel_getUrl%26m2%3D%26ts%3D1615176473%26tok%3D30feb64608edefe4b78cbabe4a91d6f5%26v%3D%26f%3Dz.apk";
        test(context, url);
    }
}

补充

Http请求结果 (对应服务器返回的json数据)
package com.hulk.android.http.conn;

/**
 * Http请求结果 (对应服务器返回的json数据)
 * <p> json:
 *  {"code":0,"msg":"Success","data":"This is response data"}
 *  此处是举例返回数据, 具体的返回数据还更具真实数据确定
 * @author: zhanghao
 * @Time: 2021-03-04 17:35
 */
public class HttpResult<T> {
    public int code = -1;
    public String msg;
    public String detail;
    public Throwable error;
    public T data = null;

    //TODO 此处是举例返回数据, 具体的返回数据还更具真实数据确定

    public HttpResult() {
    }

    public HttpResult(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public HttpResult(int code, String msg, String detail, Throwable error) {
        this.code = code;
        this.msg = msg;
        this.detail = detail;
        this.error = error;
    }

    public void setData(T data) {
        this.data = data;
    }
}

以上主要代码展示, 具体的代目可在参考源代码 https://download.csdn.net/download/zhanghao_Hulk/16020524 , 或者留言单独提供

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,以下是一个使用 OkHttpRetrofitRxJava 的简单 Android 示例。 首先,你需要在你的 build.gradle 文件中添加以下依赖: ``` dependencies { implementation 'com.squareup.okhttp3:okhttp:4.9.1' implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'io.reactivex.rxjava2:rxjava:2.2.19' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' } ``` 这样就可以使用 OkHttpRetrofitRxJava 的类和方法了。 接下来,你可以在你的代码中定义一个 Retrofit 接口: ``` public interface ApiService { @GET("users/{username}") Observable<User> getUser(@Path("username") String username); } ``` 在这个接口中,我们定义了一个 GET 请求,用于获取一个用户的信息。该请求的 URL 是 "https://api.github.com/users/{username}",其中 {username} 参数将会被替换为实际的用户名。接口返回的数据类型是 User,这是一个简单的类,如下所示: ``` public class User { public final String login; public final int id; public final String avatarUrl; public final String htmlUrl; public User(String login, int id, String avatarUrl, String htmlUrl) { this.login = login; this.id = id; this.avatarUrl = avatarUrl; this.htmlUrl = htmlUrl; } } ``` 现在,你可以在你的 Activity 或 Fragment 中调用这个接口: ``` ApiService apiService = RetrofitClient.getInstance().create(ApiService.class); apiService.getUser("octocat") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(user -> { // 在这里处理获取到的用户信息 }, throwable -> { // 在这里处理请求失败的情况 }); ``` 该示例将会获取一个名为 "octocat" 的用户的信息,并在获取到数据后将其打印出来。需要注意的是,这个网络请求是在一个新的线程中执行的,以避免阻塞主线程。获取到数据后,我们转换到主线程中,并在观察者的 onNext 回调中处理数据。如果请求失败,则在观察者的 onError 回调中处理错误情况。 希望这个简单的示例可以帮助你理解如何在 Android 中使用 OkHttpRetrofitRxJava

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值