Первое, что вам нужно понять, это метод Retrofit Call#enqueue()
, который является асинхронным.Ваш код выполняется сверху вниз.Метод среднего времени enqueue()
инициирует асинхронный запрос к API и возвращает успешный ответ на метод onResponse()
, если он успешен, иначе метод onFailure()
.
Итак, как решить проблему с кодом?
Прежде всего вам нужно создать классы POJO (если вы еще не создали) для ответа API, как показано ниже.
Article.java
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Article {
@SerializedName("source")
@Expose
private Source source;
@SerializedName("author")
@Expose
private String author;
@SerializedName("title")
@Expose
private String title;
@SerializedName("description")
@Expose
private String description;
@SerializedName("url")
@Expose
private String url;
@SerializedName("urlToImage")
@Expose
private Object urlToImage;
@SerializedName("publishedAt")
@Expose
private String publishedAt;
@SerializedName("content")
@Expose
private String content;
// constructors
// getters and setter methods
// use Alt + Insert to generate constructors, getter and setter methods in Android Studio
}
Source.java
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Source {
@SerializedName("id")
@Expose
private String id;
@SerializedName("name")
@Expose
private String name;
// constructors
// getters and setter methods
}
News.java
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class News {
@SerializedName("status")
@Expose
private String status;
@SerializedName("totalResults")
@Expose
private Integer totalResults;
@SerializedName("articles")
@Expose
private List<Article> articles = null;
// constructors
// getters and setter methods
}
Теперь в вашем классе MainFragment внесите следующие изменения,
public class MainFragment extends Fragment {
// other part of the code here
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
// other part of the code here
call.enqueue(new Callback<News>() {
@Override
public void onResponse(Call<News> call, Response<News> response) {
if (response != null && response.isSuccessful()) {
articleList = response.body().getArticles();
// request is successful just populate data in RecyclerView
populateRecyclerView();
} else {
Toast.makeText(getActivity(), "Something went wrong...", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<News> call, Throwable t) {
Toast.makeText(getActivity(), "Error in API Call", Toast.LENGTH_SHORT).show();
}
});
// just move ArrayList checking and setting adapter part code into some other method
// other part of the code here
}
private void populateRecyclerView() {
if (articleList.isEmpty() || articleList.size() == 0) {
recyclerView.setAdapter(null);
Toast.makeText(getActivity(), "Error in List", Toast.LENGTH_SHORT).show();
} else {
adapter = new NewsAdapter(articleList, getActivity());
recyclerView.setAdapter(adapter);
}
}
}
Не игнорировать Throwable объект в методе onFailure()
.Просто регистрируйте сообщения об ошибках вместо того, чтобы показывать сообщения об ошибках в Toast.
Log.e("TAG", "Error occurred...", t);
Таким образом, вы можете легко узнать, что пошло не так при выполнении запроса API.
Я пропустил некоторую часть вашего кодав моем ответе, поскольку это правильно и делает мой ответ немного длинным.Пожалуйста, просмотрите название метода и комментарии, которые я правильно использовал в своем ответе.