简体   繁体   English

Android无法解析rxjava中的订阅方法

[英]Android can not resolve subscribe method in rxjava

Im tring to use rxjava with retrofit in android studio. 我打算在Android Studio中使用rxjava进行改造。 In fact i followed this https://code.tutsplus.com/tutorials/getting-started-with-retrofit-2--cms-27792 tutorial This is what everything that I did: 实际上,我遵循了这个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'

And i created Retrofit client and Interface subscribe method. 我创建了Retrofit客户端和Interface订阅方法。 It says cann't be resolve 说不能解决

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) {

                            }


       }
         );

I imported this in my main activity: 我在主要活动中导入了此内容:

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;

Rxplanation : Rxplanation

In the tutorial You have linked was used RxJava 1. In RxJava 2 method subscribe does not accept Subscriber class instances as arguments. 在本教程中,您已链接过使用RxJava1。在RxJava 2方法中, subscribe不接受Subscriber类实例作为参数。 You have to use: 您必须使用:

All above mentioned operators have also subscribe() method without arguments. 上面提到的所有运算符也都具有无参数的subscribe()方法。

Clean-ups 清理工作

You have some kind of mess in your dependencies. 您的依赖项中有些混乱。 Shortest list of dependencies I can come up with is: 我能想到的最简短的依赖项列表是:

// 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'

Especially, please do not use two different versions of RxAndroid or adapters as you have done: 特别是,请不要使用两个不同版本的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'

There is also no need to use of Jake Wharton's adapter as it is deprecated. 也已不再使用Jake Wharton的适配器。 Square has prepared adapter for RxJava2: Square已为RxJava2准备了适配器:

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

Sample code 样例代码

Now, when everything is configured, domain model can look like: 现在,配置完所有内容后,域模型可以如下所示:

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;
  }
}

Keep in mind I used Jackson (as it is simpler to use IMHO). 请记住,我使用了Jackson(因为使用IMHO更简单)。 Do not hesitate to use GSON annotations but be awere of that You will have to change Jackson dependency to GSON and reconfigure Retrofit service instance construction. 不要犹豫,使用GSON批注,但是您将不得不将Jackson依赖项更改为GSON并重新配置Retrofit服务实例构造。

Simple service interface: 简单的服务界面:

package com.todev.rxretrofit;

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

interface CustomService {

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

And last (but not least) usage in activity (I included all imports on purpose): 最后(但并非最不重要)在活动中的用法(我故意包括了所有进口):

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());
    }
  };
}

As you can see I used Consumer s. 如您所见,我使用了Consumer You can also use lambda expressions and use class methods instead. 您也可以使用lambda表达式,而使用类方法。

在此处输入图片说明

Notice 注意

JSON document used in this example was served by json-server from simple text file: 此示例中使用的JSON文档由json-server通过简单文本文件提供:

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

Post scriptum 投稿

Remember to add Internet permission in your Manifest: 请记住在清单中添加Internet权限:

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

Otherwise you will receive SocketException with cause: 否则,您将收到SocketException原因:

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

you should add below 3 libraries 您应该添加以下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'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM