Android无法解析rxjava中的subscribe方法

时间:2017-05-03 14:39:13

标签: android retrofit2 rx-android rx-java2

我想在android studio中使用rxjava进行改造。事实上,我遵循了这个https://code.tutsplus.com/tutorials/getting-started-with-retrofit-2--cms-27792教程 这就是我所做的一切:

compile 'com.android.support:appcompat-v7:25.1.0'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
    compile 'com.squareup.retrofit2:retrofit:2.2.0'
    compile 'com.google.code.gson:gson:2.8.0'
    compile 'com.squareup.retrofit2:converter-gson:2.2.0'
    compile 'com.android.support:recyclerview-v7:25.1.0'
    compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'
    compile 'io.reactivex.rxjava2:rxjava:2.0.9'
    compile 'io.reactivex:rxandroid:1.2.1'
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
    compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'

我创建了Retrofit客户端和接口订阅方法。它说无法解决

mService.getAnswer().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
             .subscribe(new Subscriber<SOAnswersResponse>() {
                            @Override
                            public void onCompleted() {

                            }

                            @Override
                            public void onError(Throwable e) {

                            }

                            @Override
                            public void onNext(SOAnswersResponse soAnswersResponse) {

                            }


       }
         );

我在我的主要活动中导入了这个:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import android.widget.Toast;

import com.example.android.stackoverflow.Data.Model.Item;

import com.example.android.stackoverflow.Data.Model.SOAnswersResponse;
import com.example.android.stackoverflow.Data.remote.ApiUtils;
import com.example.android.stackoverflow.Data.remote.SOService;


import java.util.ArrayList;


import io.reactivex.schedulers.Schedulers;
import io.reactivex.android.schedulers.AndroidSchedulers;
import rx.Subscriber;

2 个答案:

答案 0 :(得分:5)

<强> Rxplanation

在教程中,您使用了RxJava 1链接。在RxJava 2中,方法subscribe不接受Subscriber类实例作为参数。你必须使用:

上面提到的所有运算符都有subscribe()方法,没有参数。

<强>清洁起坐

你的依赖关系中有些混乱。我能提出的最短依赖列表是:

// Reactive extensions.
compile 'io.reactivex.rxjava2:rxjava:2.1.0'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

// Networking.
compile 'com.squareup.retrofit2:retrofit:2.2.0'
compile 'com.squareup.retrofit2:converter-jackson:2.2.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'

特别是,请不要使用两个不同版本的RxAndroid或适配器:

compile 'io.reactivex:rxandroid:1.2.1'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'

也不需要使用Jake Wharton的适配器,因为它已被弃用。 Square为RxJava2准备了适配器:

compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'

示例代码

现在,当配置完所有内容后,域模型可能如下所示:

package com.todev.rxretrofit;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;

import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(value = NON_NULL)
class Song {

  private String id;

  private String title;

  public String getId() {
    return id;
  }

  public String getTitle() {
    return title;
  }
}

请记住,我使用了杰克逊(因为它更容易使用恕我直言)。不要犹豫使用GSON注释,但必须考虑到你需要将Jackson依赖项更改为GSON并重新配置Retrofit服务实例构建。

简单的服务界面:

package com.todev.rxretrofit;

import io.reactivex.Single;
import java.util.Collection;
import retrofit2.http.GET;

interface CustomService {

  @GET("songs")
  Single<Collection<Song>> getAllSongs();
}

活动中的最后(但并非最不重要)用法(我故意包括所有导入):

package com.todev.rxretrofit;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import java.util.Collection;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.jackson.JacksonConverterFactory;

public class MainActivity extends AppCompatActivity {

  private CustomService customService = new Retrofit.Builder()
      .baseUrl("http://<api_address>:<api_port>/")
      .addConverterFactory(JacksonConverterFactory.create())
      .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
      .client(new OkHttpClient.Builder().build())
      .build()
      .create(CustomService.class);

  private CompositeDisposable disposables = new CompositeDisposable();

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    this.disposables.add(
        this.customService.getAllSongs()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(this.responseHandler, this.errorHandler));
  }

  @Override
  protected void onDestroy() {
    this.disposables.dispose();
    super.onDestroy();
  }

  private Consumer<Collection<Song>> responseHandler = new Consumer<Collection<Song>>() {
    @Override
    public void accept(Collection<Song> songs) throws Exception {
      // TODO: Handle response.
      for (Song song : songs) {
        Log.d(this.getClass().getSimpleName(), String.valueOf(song));
      }
    }
  };

  private Consumer<Throwable> errorHandler = new Consumer<Throwable>() {
    @Override
    public void accept(@NonNull Throwable throwable) throws Exception {
      // TODO: Handle error.
      Log.d(this.getClass().getSimpleName(), throwable.getLocalizedMessage());
    }
  };
}

正如您所看到的,我使用了Consumer s。您也可以使用lambda表达式并使用类方法。

enter image description here

<强>通知

此示例中使用的JSON文档由json-server从简单文本文件提供:

[
  {
    "id": 0,
    "title": "Song of Fire and Ice"  
  },
  {
    "id": 1,
    "title": "The Hanging Tree"
  }
]

发布脚本

请记住在Manifest中添加Internet权限:

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

否则,您将收到SocketException原因:

  

android.system.ErrnoException:套接字失败:EACCES(权限被拒绝)

答案 1 :(得分:0)

您应该在下面的3个库中添加

implementation 'com.squareup.retrofit2:retrofit:2.6.1'
implementation 'com.squareup.retrofit2:converter-gson:2.6.1'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'