欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

android 利用Retrofit2.0+RxJava2.0实现网络下载图片保存到本地SD卡

程序员文章站 2022-06-10 16:12:30
...

android 利用Retrofit2.0+RxJava2.0实现网络下载图片保存到本地SD卡

       在项目开发中,我们有很多需求都需要将网络图片下载到本地,并且保存到SD卡,等再次用的时候,可以从本地获取即可,这就免去了网络请求,请看效果图。

android 利用Retrofit2.0+RxJava2.0实现网络下载图片保存到本地SD卡android 利用Retrofit2.0+RxJava2.0实现网络下载图片保存到本地SD卡

首先添加Retrofit2.0及RxJava2.0依赖包

// Retrofitcompile 'com.squareup.okhttp3:okhttp:3.1.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
compile 'com.google.code.gson:gson:2.2.4'
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'

网络权限:

 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>

将URL都封装到Constants类里面:

public class Constants {

    //http://img.sccnn.com/bimg/338/34264.jpg   这是图片完整路径
    public static final String BASE_URL4 = "http://img.sccnn.com/"; //BASE_URL


}

来看ApiService接口:

public interface ApiService {

    @GET("bimg/338/{fileName}")  //{fileName}是动态码
    @Streaming                    //GET下载文件必须结合@Streaming使用
    Observable<ResponseBody> downLoadImg(@Path("fileName") String fileName);

}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.administrator.retrofit20demo.MainActivity">

   
    <Button
        android:id="@+id/btn_download"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="下载文件" />


    <ImageView
        android:src="@mipmap/ic_launcher"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/img"/>

</LinearLayout>

MainActivity 代码如下:


 Bitmap bitmap = null;

    private void downLoadImg() {


        new Thread(new Runnable() {
            @Override
            public void run() {
                //OK设置请求超时时间,读取超时时间
                OkHttpClient client = new OkHttpClient.Builder()
                        .connectTimeout(15, TimeUnit.SECONDS)
                        .readTimeout(15, TimeUnit.SECONDS)
                        .build();
                Retrofit retrofit = new Retrofit.Builder().baseUrl(Constants.BASE_URL4)
                        .addConverterFactory(GsonConverterFactory.create())
                        .client(client)
                        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                        .build();

                ApiService apiService = retrofit.create(ApiService.class);
                Observable<ResponseBody> observable = apiService.downLoadImg("34264.jpg");


                observable.subscribeOn(Schedulers.io()) 
                        .subscribe(new Observer<ResponseBody>() {
                            @Override
                            public void onSubscribe(Disposable d) {

                            }

                            @Override
                            public void onNext(ResponseBody value) {
                                byte[] bys = new byte[0];
                                try {
                                    bys = value.bytes(); //注意:把byte[]转换为bitmap时,也是耗时操作,也必须在子线程
                                    bitmap = BitmapFactory.decodeByteArray(bys, 0, bys.length);
                                    runOnUiThread(new Runnable() {//开启主线程更新UI
                                        @Override
                                        public void run() {
                                            img.setImageBitmap(bitmap);

                                            try {//调用saveFile方法
                                                saveFile(bitmap, Environment.getExternalStorageDirectory() + "/imgpic/");
                                                Log.e("TAG", Environment.getExternalStorageDirectory() + "/imgpic/");
                                            } catch (IOException e) {
                                                e.printStackTrace();
                                            }
                                        }
                                    });

                                } catch (IOException e) {
                                    e.printStackTrace();
                                }

                            }

                            @Override
                            public void onError(Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        });


            }
        }).start();
    }

注意:要始终分清网络请求必须在子线程中进行,UI在主线程进行,否则这里很容易报错(线程问题);需谨慎。

来看一个保存到SD卡的方法:

 //保存图片到SD卡
    public void saveFile(Bitmap bm, String fileName) throws IOException {

        String imgName = UUID.randomUUID().toString() + ".jpg"; //随机生成不同的名字
        File jia = new File(fileName);              //新创的文件夹的名字
        if (!jia.exists()) {   //判断文件夹是否存在,不存在则创建
            jia.mkdirs();
        }
        File file = new File(jia + "/" + imgName);
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
        bm.compress(Bitmap.CompressFormat.JPEG, 80, bos);

        bos.flush();
        bos.close();

    }

相关标签: android进阶