android 利用Retrofit2.0+RxJava2.0实现网络下载图片保存到本地SD卡_MrZhao_PerfectCode的博客-CSDN博客

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

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

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

// Retrofit__库 compile '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();     }

原网址: 访问
创建于: 2021-10-11 11:35:20
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论