Получить данные из onNext в Retrofit rxjava - PullRequest
0 голосов
/ 04 июля 2019

В этом списке (в части list.get (9)) указан String ArrayList.Я пытаюсь получить все имя пользователя от пользователей и добавить его в список, а затем показать 10-е имя в текстовом представлении.

Когда я запускаю приложение, оно выдает ошибки в изображении, которое я связал ниже, ошибка является индексом вне границв textView.setText (list.get (9)).Но это работает, когда я комментирую эту строку и устанавливаю текст для моего просмотра текста с помощью кнопки onclick.

Вот API в моем примере.https://jsonplaceholder.typicode.com/users

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

    //init api
    Retrofit retrofit = RetrofitClient.getInstance();
    btnOk = findViewById(R.id.btn_ok);
    myAPI = retrofit.create(IMyAPI.class);
    textView = findViewById(R.id.show);

    //fetchData()

    fetchUserData();

    textView.setText(list.get(9));
    btnOk.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            textView.setText(list.get(9));
        }
    });

}

private void fetchUserData() {
    myAPI.getUsers()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<ArrayList<User>>() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(ArrayList<User> users) {
                    String usName ;
                    for(int i = 0; i < users.size(); i++){
                        usName = posts.get(i).getUsername();
                        list.add(usName);
                    }
                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onComplete() {

                }
            });

}

Ошибка в строке textView.settext

Ответы [ 3 ]

0 голосов
/ 04 июля 2019

ваш вызов textView.setText(list.get(9)); в вашем методе onCreate, в то время как list все еще пуст, что вызывает IndexOutOfBoundsException.Удалите его из формы onCreate и поместите в метод onNext:

public void onNext(ArrayList<User> users) {
     String usName ;
     for(int i = 0; i < users.size(); i++){
         usName = posts.get(i).getUsername();
         list.add(usName);
     }
     textView.setText(list.get(9));
}
0 голосов
/ 04 июля 2019

В вашем коде есть ошибки, которые могут вызвать IndexOutOfBoundsException.

Я добавлю несколько комментариев в ваш код:

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

    //init api
    Retrofit retrofit = RetrofitClient.getInstance();
    btnOk = findViewById(R.id.btn_ok);
    myAPI = retrofit.create(IMyAPI.class);
    textView = findViewById(R.id.show);

    fetchUserData();


    // this line should be removed cause you didn't get yet the result of fetchUserData(). Instead you should do this on the onNext method.
    // textView.setText(list.get(9)); 

    btnOk.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            // Before accessing the list, you must ensure your list contains at least 9 elements. Otherwise it could crash.
            // textView.setText(list.get(9));

            // This would be the correct way
            if (list != null && list.size > 9) {
               textView.setText(list.get(9));
            }
        }
    });

}

private void fetchUserData() {
    myAPI.getUsers()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<ArrayList<User>>() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(ArrayList<User> users) {
                    String usName ;
                    for(int i = 0; i < users.size(); i++){
                        usName = posts.get(i).getUsername();
                        list.add(usName);
                    }
                    // This is the place where you are safe to access the users list, so any View component you want to update with the users list should be done here.
                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onComplete() {

                }
            });

}

Помните, что вы используете Rx для вызова asynchronous, вам следует подождать, пока метод onNext не будетвызывается перед выполнением любых операций с результатом.

0 голосов
/ 04 июля 2019

Хорошо, проблема в том, что myAPI.getUsers() запускается в потоке io, что требует времени для заполнения и заполнения list именем пользователя. С другой стороны, textView.setText(list.get(9)); срабатывает немедленно. Следовательно, правильный поток - это textView.setText(list.get(9)); в onNext или onComplete, эти методы будут запущены, когда myAPI.getUsers() завершит

...