美文网首页
第四单元

第四单元

作者: 贤兵 | 来源:发表于2020-12-10 07:46 被阅读0次

一、RxJava

1、什么是观察者模式

指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新

2、什么是RxJava

RxJava:a library for composing asynchronous and event-based programs using observable sequences for the Java VM
RxJava 是一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库
RxJava 是一个 基于事件流、实现异步操作的库
https://github.com/ReactiveX/RxJava

3、RxJava特点

逻辑简洁,实现优雅,使用简单

4、RxJava四个角色

被观察者(Observable) 产生事件
观察者(Observer) 接收事件并处理
订阅(Subscribe) 连接 被观察者和观察者
事件(Event)

5、步骤

1、创建被观察者,生产事件
2、创建观察者并定义相应事件行为
3、通过订阅连接观察者和被观察者
4、解除订阅!!!!!!!

6、简单例子

private void demo1() {
        Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onNext(4);
                emitter.onComplete();
            }
        });

        Observer observer = new Observer() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.i("Simon", "onSubscribe");
            }

            @Override
            public void onNext(Object o) {
                Log.i("Simon", "onNext: " + o);
            }

            @Override
            public void onError(Throwable e) {
                Log.i("Simon", "onError");
            }

            @Override
            public void onComplete() {
                Log.i("Simon", "onComplete");
            }
        };

        observable.subscribe(observer);
    }

7、倒计时例子

private Disposable mDisposable;
    private void demo2() {
        Observable.interval(0, 1, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.computation())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        mDisposable = d;
                        Log.i("Simon", "interval onSubscribe");
                    }

                    @Override
                    public void onNext(@NonNull Long aLong) {
                        Log.i("Simon", "interval onNext aLong: " + aLong);

                        if (aLong > 10) {
                            if (mDisposable != null) {
                                mDisposable.dispose();
                            }
                        }
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.i("Simon", "interval onError e: " + e.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.i("Simon", "interval onComplete");
                    }
                });
    }

8、操作符例子

    private void operatorDemo() {
        //just
        Observable.just(1, 2, 3, 4).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                Log.i("Simon", "just: " + integer);
            }
        });
        //map
        Observable.just(1, 2, 3, 4).map(new Function<Integer, String>() {
            @Override
            public String apply(Integer integer) throws Exception {
                return "i get " + integer;
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.i("Simon", "map: " + s);
            }
        });
        //flatmap
        //flatMap将一个发送事件的上游Observable变换为多个发送事件的Observables,然后将它们发射的事件合并后放进一个单独的Observable里
        Observable.just("张无忌", "赵敏", "小昭").flatMap(new Function<String, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(String name) throws Exception {
                List<String> list = new ArrayList<>();
                for (int i = 0; i < 3; i++) {
                    list.add(name + ":" + i);
                }
                return Observable.fromIterable(list);
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String str) throws Exception {
                Log.i("Simon", "" + str);
            }
        });
        //merge
        Observable o1 = Observable.just(1, 2, 3);
        Observable o2 = Observable.just(4, 5, 6);
        Observable.merge(o1, o2).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer o) throws Exception {
                Log.i("Simon", "merge :" + o);
            }
        });
    }

二、Retrofit

1、什么是Retrofit

Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装,网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责 网络请求接口的封装

2、如何使用

1、依赖

   //RxJava依赖
    implementation 'io.reactivex.rxjava2:rxjava:2.2.6'
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'


   //Retrofit依赖
    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
   //Gson converter gson解析
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'

    //RxJava2 Adapter
    implementation "com.squareup.retrofit2:adapter-rxjava2:2.3.0"
    //okhttp
    implementation 'com.squareup.okhttp3:okhttp:3.4.1'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.9.1'

2、权限

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

3、接口定义

public interface XiaService {
    //    http://www.qubaobei.com/ios/cf/dish_list.php?stage_id=1&limit=20&page=1
    @GET("/ios/cf/dish_list.php")
    Call<Xia> getXiaService(@Query("stage_id") int stage_id, @Query("limit") int limit, @Query("page") int page);
}

4、发出请求

private void requestXia() {
    Retrofit retrofit = new Retrofit
            .Builder()
            .baseUrl("http://www.qubaobei.com")
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    XiaService xiaService = retrofit.create(XiaService.class);

    Call<Xia> call = xiaService.getXiaService(1, 5, 2);
    call.enqueue(new Callback<Xia>() {
        @Override
        public void onResponse(Call<Xia> call, Response<Xia> response) {
            Log.i("Simon", "requestXia onResponse response: " + response.body().toString());
        }

        @Override
        public void onFailure(Call<Xia> call, Throwable t) {
            Log.e("Simon", "requestXia onFailure: " + t.toString());
        }
    });
}

5、加上 RxJava

public interface XiaServiceRX {
    @GET("/ios/cf/dish_list.php")
    Observable<Xia> getXiaService(@Query("stage_id") int stage_id, @Query("limit") int limit, @Query("page") int page);
}
private void requestXia2() {
    Retrofit retrofit = new Retrofit
            .Builder()
            .baseUrl("http://www.qubaobei.com")
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build();

    XiaServiceRX xiaService = retrofit.create(XiaServiceRX.class);
    xiaService.getXiaService(1,5,1)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<Xia>() {
                @Override
                public void onSubscribe(@NonNull Disposable d) {
                    Log.i("Simon", "requestXia2 onSubscribe");
                }
                @Override
                public void onNext(@NonNull Xia xia) {
                    Log.i("Simon", "requestXia2 onNext: " + xia.toString());
                }
                @Override
                public void onError(@NonNull Throwable e) {
                    Log.e("Simon", "requestXia2 onError: " + e.toString());
                }
                @Override
                public void onComplete() {
                    Log.i("Simon", "requestXia2 onComplete");
                }
            });
}

6、下载文件

//下载回调
public interface DownloadListener {
    void onStart();//下载开始
    void onProgress(int progress);//下载进度
    void onFinish(String path);//下载完成
    void onFail(String errorInfo);//下载失败
}
//service定义,注意@Streaming和@Url 
public interface DownloadService {
    @Streaming
    @GET
    Call<ResponseBody> download(@Url String url);
}
//真正下载的地方
public class RetrofitDownloader {
    private static final int BUFFER_SIZE = 8192;

    public static void download(String url, final String path, final DownloadListener downloadListener) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://www.baidu.com")//和下载无关,但是需要写上一个地址
                .build();

        DownloadService service = retrofit.create(DownloadService.class);

        Call<ResponseBody> call = service.download(url);
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(@NonNull Call<ResponseBody> call, @NonNull final Response<ResponseBody> response) {
                writeResponseToDisk(path, response, downloadListener);
            }

            @Override
            public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable throwable) {
                downloadListener.onFail("下载失败");
            }
        });
    }

    private static void writeResponseToDisk(String path, Response<ResponseBody> response, DownloadListener downloadListener) {
        writeFileFromIS(new File(path), response.body().byteStream(), response.body().contentLength(), downloadListener);
    }

    private static void writeFileFromIS(File file, InputStream is, long totalLength, DownloadListener downloadListener) {
        downloadListener.onStart();

        if (!file.exists()) {
            if (!file.getParentFile().exists())
                file.getParentFile().mkdir();
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
                downloadListener.onFail("新建文件失败");
            }
        }

        OutputStream os = null;
        long currentLength = 0;
        try {
            os = new BufferedOutputStream(new FileOutputStream(file));
            byte data[] = new byte[BUFFER_SIZE];
            int len;
            while ((len = is.read(data, 0, BUFFER_SIZE)) != -1) {
                os.write(data, 0, len);
                currentLength += len;
                //计算当前下载进度
                downloadListener.onProgress((int) (100 * currentLength / totalLength));
            }
            //下载完成,并返回保存的文件路径
            downloadListener.onFinish(file.getAbsolutePath());
        } catch (IOException e) {
            e.printStackTrace();
            downloadListener.onFail("下载失败 exception:" + e.toString());
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
//ui中点击按钮开始下载
    private void download() {
        //网络图片
        String url = "http://img21.mtime.cn/CMS/Gallery/2011/07/07/200129.45747105_900.jpg";
        RetrofitDownloader.download(url, "/sdcard/hsw.jpg", new DownloadListener() {
            @Override
            public void onStart() {
                Log.i("Simon", "onStart");
            }

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

            @Override
            public void onFinish(String path) {
                Log.i("Simon", "onProgress onFinish path: " + path);
            }

            @Override
            public void onFail(String errorInfo) {
                Log.i("Simon", "onProgress onFail errorInfo: " + errorInfo);
            }
        });
    }

7、上传文件
接口定义

public interface UploadDownloadService {
    @Streaming
    @GET
    Call<ResponseBody> download(@Url String url);


    @Multipart
    @POST("upload")
    Call<ResponseBody> uploadFile(@Part List<MultipartBody.Part> multipartBody);
}

真正的上传

public class RetrofitUploader {
    private static final String RETROFIT_BASE_URL = "http://192.168.18.6:1323/";

    public void uploadFile(File file, final String fileName, final Observer<FileEntity> observer) {
        RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);

        MultipartBody multipartBody = new MultipartBody.Builder()
                .addFormDataPart("file", fileName, requestBody)
                .setType(MultipartBody.FORM)
                .build();

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(20, TimeUnit.MINUTES)
                .readTimeout(20, TimeUnit.MINUTES)
                .addInterceptor(interceptor)
                .build();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(RETROFIT_BASE_URL)
                .client(okHttpClient)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();

        UploadDownloadService uploadDownloadService = retrofit.create(UploadDownloadService.class);
        uploadDownloadService.uploadFile(multipartBody.parts())
                .enqueue(new Callback<ResponseBody>() {
                    @Override
                    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                        Log.e("Simon", "onResponse" + response.body());
                        FileEntity fileEntity = new FileEntity();
                        fileEntity.fileUrl = RETROFIT_BASE_URL + fileName;
                        observer.onNext(fileEntity);
                    }

                    @Override
                    public void onFailure(Call<ResponseBody> call, Throwable t) {
                        Log.e("Simon", "onFailure" + t.getMessage());
                        observer.onError(t);
                    }
                });
    }

    public static class FileEntity {
        public String fileUrl;
    }

}

ui调用下载

    private void upload() {
        RetrofitUploader retrofitUploader = new RetrofitUploader();
        retrofitUploader.uploadFile(new File("/sdcard/hsw2.jpg"), "hsw2_ha.jpg", new Observer<RetrofitUploader.FileEntity>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
            }

            @Override
            public void onNext(@NonNull RetrofitUploader.FileEntity fileEntity) {
                Log.i("Simon", "uploadFile " + fileEntity.fileUrl);
            }

            @Override
            public void onError(@NonNull Throwable e) {
            }

            @Override
            public void onComplete() {
            }
        });
    }

上传的服务器实现(使用echo:https://echo.labstack.com/

package main

import (
    "fmt"
    "io"
    "os"

    "net/http"

    "github.com/labstack/echo"
    "github.com/labstack/echo/middleware"
)

func upload(c echo.Context) error {
    // Read form fields
    name := c.FormValue("name")
    email := c.FormValue("email")

    //-----------
    // Read file
    //-----------

    // Source
    file, err := c.FormFile("file")
    if err != nil {
        return err
    }
    src, err := file.Open()
    if err != nil {
        return err
    }
    defer src.Close()

    // Destination
    dst, err := os.Create(file.Filename)
    if err != nil {
        return err
    }
    defer dst.Close()

    // Copy
    if _, err = io.Copy(dst, src); err != nil {
        return err
    }

    return c.HTML(http.StatusOK, fmt.Sprintf("<p>File %s uploaded successfully with fields name=%s and email=%s.</p>", file.Filename, name, email))
}

func main() {
    e := echo.New()

    e.Use(middleware.Logger())
    e.Use(middleware.Recover())

    e.Static("/", "public")
    e.POST("/upload", upload)

    e.Logger.Fatal(e.Start(":1323"))
}

8、注解
方法注解:@GET、@POST、@PUT、@DELETE、@PATCH、@HEAD、@OPTIONS、@HTTP
标记注解:@FormUrlEncoded、@Multipart、@Streaming
参数注解:@Query、@QueryMap、@Body、@Field、@FieldMap、@Part、@PartMap
其他注解:@Path、@Header、@Headers、@HeaderMap、@Url

@Query:URL后面有参数
@QueryMap:URL后面有多个参数
@FormUrlEncoded:是一个form表单,用于修饰@Field、@FieldMap注解,具”application / x-www-form-urlencoded” MIME类型
@Field:表单字段,需要和@FormUrlEncoded配合使用
@FieldMap:表单字段,需要和@FormUrlEncoded配合使用
@Streaming:下载使用
@Url:重新定义Url

补充:
https://www.jianshu.com/p/7687365aa946

相关文章

  • 词语盘点

    第三单元 第五单元 第四单元

  • 部编语文八上阅读文体知识与层次结构

    第一单元 第二单元 第三单元 第四单元 第五单元 第六单元

  • 第659期【随文写作】

    第四单元随文写作 文/张永刚 第四单元的选文,从不同...

  • 记叙文应有画面感——第四单元作文评讲

    记叙文应有画面感 ——第四单元作文评讲 第四单元作文训练:思路要清...

  • 今日所学

    语文课上学的是动物儿歌,蜻蜓是益虫,蝌蚪是益虫,蜘蛛是益虫,数学课上老师讲了第四单元一和第四单元二,第四单元一的背...

  • 第四单元

    各位老师,大家好哈! 今天继续大英展哈~咱们进入第四单元。 第四单元 权利与信仰 (1~800) 本单元共11件文...

  • 2022-01-30

    第四课认知第一讲感觉和知觉 第一单元感觉概述。第二单元感受性与感觉阈限。第三单元感觉现象。第四单元各种感觉。第五单...

  • 2018-10-20

    第四单元测试卷

  • 我和———过一天

    四上第四单元习作

  • 期中考试的前一晚

    明天就要语文期中考试了,我今天晚上写完所有作业后就抓起语文课本,从第一单元复习到第四单元,又从第四单元复习回...

网友评论

      本文标题:第四单元

      本文链接:https://www.haomeiwen.com/subject/fkpkgktx.html