android 利用Retrofit2.0+RxJava2.0实现网络下载图片保存到本地SD卡 - Go语言中文社区

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


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

       在项目开发中,我们有很多需求都需要将网络图片下载到本地,并且保存到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();

    }

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/MrZhao_PerfectCode/article/details/80055862
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-01 22:39:46
  • 阅读 ( 1413 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢