Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android 练手之旅——RxAndroid&OKHttpClient(一) #5

Open
soapgu opened this issue Feb 25, 2021 · 0 comments
Open

Android 练手之旅——RxAndroid&OKHttpClient(一) #5

soapgu opened this issue Feb 25, 2021 · 0 comments
Labels
Demo Demo ReactiveX ReactiveX 安卓 安卓

Comments

@soapgu
Copy link
Owner

soapgu commented Feb 25, 2021

前言Blibli

Photo Hunter之旅暂停下。主要功能马马虎虎完成。不能在原有代码上继续了,因为代码实在太难看了。需要切出分支来优化下代码。
使用OKHttpClient组件的Callback回调后,特别是两次回调后,嵌套代码层有点代码坏味道。但是安卓JAVA没有协程库,可以把多个异步操作给串联起来。
RX,全名ReactiveX。中文翻译会响应式编程。这个库是一个科学家带着团队研发的,(我怎么觉得应该是个哲学家)。当初在.net环境下使用过这个库。WPF和.net core 平台上都使用过,其实.net平台上起步还是很早的。
这个库的思想是很反人类的,从物理上讲就是反物质,

  • 他的核心思想就是变化,这个事件是完全相反操作的思想,事件其实是时间轴的静态切片,你+= 后面的处理函数是这刻是静止的,而Rx的Observable是个的对象,也叫可观察对象。也叫事件流(数据流),你可以脑补下,这个对象不停的在动
  • 变化是可以被订阅的,你可以通过订阅他变化出来的值
  • 运算处理,形似Linq又不是Linq,因为Linq是静态的,就是说Linq在运行的那一个刹那,他的数据是确定的。但是Observable是在动的。但是行为有又有相似的Where,Aggregation操作等。又有很多非常有特色有用的操作,如Repeat,Retry等等
  • 非常优秀的线程控制API和模型,Rx有一个发布者线程和订阅者线程。两者可以相互联系又不需要耦合线程
  • 针对复杂场景适用性,Rx库有着得天独厚的优势,特别是异步场景。可以把碎片化的代码粘合起来,特别是EventHandl,BeginXXXX,EndXXXX(令人崩溃的Socket操作碎片API),Callback等等

由于Android的JAVA语言环境下不支持协程。Rx就变成了非常合适的团结对象。其实.net 在推出了aync await以后Rx就基本没必要使用了,双方都有互相替代的方案。

代码实现部分

废话太多了直接开干
build.gradle for Project

allprojects {
    repositories {
        google()
        jcenter()
        maven { url "https://oss.jfrog.org/libs-snapshot" }
    }
}

build.gradle for Module

dependencies {

    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'com.google.android.material:material:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
    implementation 'io.reactivex.rxjava3:rxjava:3.0.0'
    implementation("com.squareup.okhttp3:okhttp:4.9.0")
    implementation 'com.orhanobut:logger:2.2.0'
    implementation 'com.google.code.gson:gson:2.8.6'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

写一个返回Json泛型对象的的Observable,把大量的细节都封装起来。
小小吐槽下泛型,有点不一样,卡壳了好久

private <T> Observable<T> HttpJsonObservable( Call call , Class<T> classOfT )
    {
        return Observable.create(subscriber -> {
            Logger.i( "------Begin To Request Http Thread:%s",  Thread.currentThread().getId() );
            call.enqueue(new Callback() {
                @Override
                public void onFailure(@NotNull Call call, @NotNull IOException e) {
                    Logger.i("------- Http Error:%s",  e.getMessage() );
                    subscriber.onError( e );
                }

                @Override
                public void onResponse(@NotNull Call call, @NotNull Response response) {
                    Logger.i("------- Http Response Thread:%s",  Thread.currentThread().getId() );
                    try (ResponseBody body = response.body()){
                        if( response.isSuccessful() ) {
                            try {
                                String json = body.string();
                                Gson gson = new Gson();

                                T jsonObj = gson.fromJson(json,classOfT );
                                subscriber.onNext(jsonObj);
                                subscriber.onComplete();
                            } catch (IOException e) {
                                subscriber.onError(e);
                            }
                        }
                        else
                        {
                            subscriber.onError( new Exception( String.format( "error state code: %s", response.code() ) ) );
                        }
                    }
                }
            });
        });
    }

调用部分处理

       textView = this.findViewById((R.id.msg_view));
       this.findViewById(R.id.button).setOnClickListener( v -> {
           Request request = new Request.Builder()
                   .url(url)
                   .get()
                   .build();
           Call call = client.newCall(request);
           HttpJsonObservable(call,Photo.class)
           .observeOn(AndroidSchedulers.mainThread())
           .subscribe( t -> this.textView.setText(t.alt_description),
                       error -> this.textView.setText(error.getMessage())
           );
       } );

接下来就可以看到图片信息了
未完待续。只是起了一个头。还没做到要想要的那种效果。
Rx的Java库还是不熟,需要一点时间查资料学习(目前的经验全在Rx.net里面,主要api应该都有对标项的)。但是我相信一定是能完成的
我的设计思路是这样
1 访问API产生json是一个Observable
2 下载图片产生Image是另外一个Observable
3 两个Observable做链式串联
4 订阅者只要做做收尾工作就行了,赋值下图片信息,呈现下图片

[另外我还想把下载处理图片的这部分功能用 glide换掉,看文档代码简单到令人发指,一步步来吧

仓库地址

传送门

参考资料

今天晚上不更新了,给儿子做兔子灯(●ˇ∀ˇ●)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Demo Demo ReactiveX ReactiveX 安卓 安卓
Projects
None yet
Development

No branches or pull requests

1 participant