Retrofit 中的 Enqueue 方法不会在 Fragment 中加载数据
Posted
技术标签:
【中文标题】Retrofit 中的 Enqueue 方法不会在 Fragment 中加载数据【英文标题】:Enqueue method in Retrofit doesn't load data in Fragment 【发布时间】:2020-09-18 03:19:54 【问题描述】:在过去的 3 天里,我感到震惊,无法使用改造 2.4.0 在 Fragment 中的 recyclerview 上加载数据。我可以在终端中看到数据是使用真实 url 从服务器获取的,但无法填充它(意味着当我调试代码时跳过 OnReponse 和 OnFailure)。此外,我可以在应用程序 UI 上看到一些垃圾值。在这方面已经回答了一些问题,但没有一个解决方案对我有用。即使我在 github 上进行了研究,但在那里没有找到任何解决方案。到目前为止,我有以下代码。
public interface UserAPIEndPoint
@GET("posts")
Call<List<Post>> getAllUsers();
以下是改造实例
public class RetrofitInstance
public static Retrofit retrofit;
private static final String base_Url = "https://jsonplaceholder.typicode.com/";
public static Retrofit getRetrofitInstance()
if (retrofit == null)
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
retrofit = new Retrofit.Builder()
.baseUrl(base_Url)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit;
这里是片段类
public class MessageFragment extends Fragment
private RecyclerView recyclerView;
private List<Post> user;
private PostAdapter userAdapter;
private LinearLayoutManager layoutManager;
View rootView;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
rootView = inflater.inflate(R.layout.fragment_message,container,false);
loadJSON();
return rootView;
private void loadJSON()
try
UserAPIEndPoint userAPIEndPoint= RetrofitInstance.getRetrofitInstance().create(UserAPIEndPoint.class);
Call<List<Post>> userlist = userAPIEndPoint.getAllUsers();
// userlist.execute();
userlist.enqueue(new Callback<List<Post>>()
@Override
public void onResponse(Call<List<Post>> call, Response<List<Post>> response)
user = response.body();
recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerview);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
userAdapter = new PostAdapter(getActivity(),user);
recyclerView.setAdapter(userAdapter);
@Override
public void onFailure(Call<List<Post>> call, Throwable t)
);
catch (Exception e)
Log.d("Error", e.getMessage());
Toast.makeText(getActivity(), e.toString(), Toast.LENGTH_SHORT).show();
Post.class 通过 pojo2schema 进行转换。 RecyclerAdapter如下。
public class PostAdapter extends RecyclerView.Adapter<PostAdapter.ViewHolder>
private List<Post> posts;
private Context mcontext;
public PostAdapter(Context context,List<Post> post)
this.posts = post;
this.mcontext =context;
@NonNull
@Override
public PostAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout_post,parent,false);
return new ViewHolder(view);
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position)
holder.userid.setText(String.valueOf(posts.get(position).getUserId()));
holder.id.setText(String.valueOf(posts.get(position).getId()));
holder.title.setText(posts.get(position).getTitle());
holder.body.setText(posts.get(position).getBody());
@Override
public int getItemCount()
return posts.size();
public class ViewHolder extends RecyclerView.ViewHolder
private TextView userid,id,title,body;
public ViewHolder(View itemView)
super(itemView);
userid = (TextView) itemView.findViewById(R.id.userId);
id = (TextView) itemView.findViewById(R.id.id);
title = (TextView) itemView.findViewById(R.id.title);
body = (TextView) itemView.findViewById(R.id.body);
build.gradle(模块:app)
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
android
compileSdkVersion 28
defaultConfig
applicationId "com.example.scratchnavigation"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
buildTypes
release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
dependencies
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "androidx.core:core:1.4.0-alpha01"
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.1.0-alpha04'
implementation 'com.google.firebase:firebase-core:16.0.3'
implementation 'com.google.firebase:firebase-auth:16.0.3'
implementation 'com.miguelcatalan:materialsearchview:1.4.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
testImplementation 'junit:junit:4.13'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'de.hdodenhof:circleimageview:3.1.0'
implementation "androidx.cardview:cardview:1.0.0"
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation "androidx.drawerlayout:drawerlayout:1.0.0"
implementation "androidx.cardview:cardview:1.0.0"
implementation 'com.squareup.okhttp3:logging-interceptor:4.7.2'
implementation 'com.squareup.okhttp3:okhttp:4.7.2'
implementation 'org.conscrypt:conscrypt-android:2.4.0'
我们非常感谢这方面的任何帮助。提前致谢。
【问题讨论】:
【参考方案1】:我相信这是因为它是一个异步网络调用。您在不同的线程中创建所有内容。
有两种方法可以解决这个问题。
1.) 尝试创建一个处理程序以在主线程上发布数据集已更改的内容,例如
Handler mHandler = new Handler(Looper.getMainLooper());
mHandler.post(new Runnable()
@Override
public void run()
userAdapter = new PostAdapter(user);
recyclerView.setAdapter(userAdapter);
if (userAdapter != null)
userAdapter.notifyDataSetChanged(userAdapter);
recyclerView.setVerticalScrollbarPosition(userAdapter.getItemCount());
recyclerView.smoothScrollToPosition(userAdapter.getItemCount());
);
2.) 在 onCreateView 中分配 recyclerView 和 Adapter 所以它看起来像:
public class MessageFragment extends Fragment
private RecyclerView recyclerView;
private List<Post> user;
private PostAdapter userAdapter;
private LinearLayoutManager layoutManager;
View rootView;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
rootView = inflater.inflate(R.layout.fragment_message,container,false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerview);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
userAdapter = new PostAdapter(getActivity(), null);
recyclerView.setAdapter(userAdapter);
loadJSON();
return rootView;
private void loadJSON()
try
UserAPIEndPoint userAPIEndPoint= RetrofitInstance.getRetrofitInstance().create(UserAPIEndPoint.class);
Call<List<Post>> userlist = userAPIEndPoint.getAllUsers();
userlist.enqueue(new Callback<List<Post>>()
@Override
public void onResponse(Call<List<Post>> call, Response<List<Post>> response)
user = response.body();
userAdapter.setData(user);
@Override
public void onFailure(Call<List<Post>> call, Throwable t)
);
catch (Exception e)
Log.d("Error", e.getMessage());
Toast.makeText(getActivity(), e.toString(), Toast.LENGTH_SHORT).show();
然后您还可以为该方法修改 PostsAdapter
public class PostAdapter extends RecyclerView.Adapter<PostAdapter.ViewHolder>
private List<Post> posts;
private Context mcontext;
public PostAdapter(Context context,List<Post> post)
this.posts = post;
this.mcontext =context;
@NonNull
@Override
public PostAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout_post,parent,false);
return new ViewHolder(view);
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position)
holder.userid.setText(String.valueOf(posts.get(position).getUserId()));
holder.id.setText(String.valueOf(posts.get(position).getId()));
holder.title.setText(posts.get(position).getTitle());
holder.body.setText(posts.get(position).getBody());
@Override
public int getItemCount()
return posts.size();
public void setData(@NonNull List<Posts> list)
if(list.size() > 0)
posts = list;
this.noftifyDataSetChanged();
public class ViewHolder extends RecyclerView.ViewHolder
private TextView userid,id,title,body;
public ViewHolder(View itemView)
super(itemView);
userid = (TextView) itemView.findViewById(R.id.userId);
id = (TextView) itemView.findViewById(R.id.id);
title = (TextView) itemView.findViewById(R.id.title);
body = (TextView) itemView.findViewById(R.id.body);
【讨论】:
以上是关于Retrofit 中的 Enqueue 方法不会在 Fragment 中加载数据的主要内容,如果未能解决你的问题,请参考以下文章