我尝试使用Retrofit和GSON的嵌套JSON API。代码没有错误。但问题是当我运行应用程序时,它显示空白活动。我使用AndroidX布局的layout_activity,并使用RecyclerView的列表。
这里是完整的代码,请检查它为我,如果我可以继续下去。
我的活动
package com.example.retrofitnested;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private DataAdapter adapter;
ApiInterface apiInterface;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.card_recycler_view);
RecyclerView.LayoutManager layoutManager = new
LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
loadData();
}
private void loadData() {
apiInterface = ApiClient.getClient().create(ApiInterface.class);
apiInterface.getMovies().enqueue(new Callback<Movie>() {
@Override
public void onResponse(Call<Movie> call, Response<Movie> response) {
if (response.isSuccessful()) {
List<Contact> contactList = response.body().getContacts();
for (int i = 0; i<contactList.size(); i++) {
adapter = new DataAdapter((ArrayList<Contact>) contactList);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
else {
System.out.println("Server Error");
return;
}
}
@Override
public void onFailure(Call<Movie> call, Throwable t) {
}
});
}
}
型号类电话
package com.example.retrofitnested;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Phone {
@SerializedName("mobile")
@Expose
private String mobile;
@SerializedName("home")
@Expose
private String home;
@SerializedName("office")
@Expose
private String office;
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getHome() {
return home;
}
public void setHome(String home) {
this.home = home;
}
public String getOffice() {
return office;
}
public void setOffice(String office) {
this.office = office;
}
}
模型类联系人
package com.example.retrofitnested;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Contact {
@SerializedName("id")
@Expose
private String id;
@SerializedName("name")
@Expose
private String name;
@SerializedName("email")
@Expose
private String email;
@SerializedName("address")
@Expose
private String address;
@SerializedName("gender")
@Expose
private String gender;
@SerializedName("phone")
@Expose
private Phone phone;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Phone getPhone() {
return phone;
}
public void setPhone(Phone phone) {
this.phone = phone;
}
}
班级电影
package com.example.retrofitnested;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class Movie {
@SerializedName("contacts")
@Expose
private List<Contact> contacts = null;
public List<Contact> getContacts() {
return contacts;
}
public void setContacts(List<Contact> contacts){
this.contacts = contacts;
}
}
API客户端类
package com.example.retrofitnested;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class ApiClient {
public static final String BASE_URL="https://api.androidhive.info";
private static Retrofit retrofit=null;
public static final Retrofit getClient(){
if (retrofit==null){
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
数据适配器类
package com.example.retrofitnested;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
private ArrayList<Contact> arrayList;
public DataAdapter(ArrayList<Contact> arrayList) {
this.arrayList = arrayList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.card_layout, viewGroup,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
viewHolder.tv_id.setText(arrayList.get(i).getId());
viewHolder.tv_name.setText(arrayList.get(i).getName());
viewHolder.tv_email.setText(arrayList.get(i).getEmail());
viewHolder.tv_address.setText(arrayList.get(i).getAddress());
viewHolder.tv_gender.setText(arrayList.get(i).getGender());
viewHolder.tv_mobile.setText(arrayList.get(i).getPhone().getMobile());
viewHolder.tv_home.setText(arrayList.get(i).getPhone().getHome());
viewHolder.tv_office.setText(arrayList.get(i).getPhone().getOffice());
}
@Override
public int getItemCount() {
return arrayList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tv_id, tv_name, tv_email, tv_address, tv_gender, tv_mobile, tv_home, tv_office;
public ViewHolder(@NonNull View itemView) {
super(itemView);
tv_id = (TextView) itemView.findViewById(R.id.tv_id);
tv_name = (TextView) itemView.findViewById(R.id.tv_name);
tv_email = (TextView) itemView.findViewById(R.id.tv_email);
tv_address = (TextView) itemView.findViewById(R.id.tv_address);
tv_gender = (TextView) itemView.findViewById(R.id.tv_gender);
tv_mobile = (TextView) itemView.findViewById(R.id.tv_mobile);
tv_home = (TextView) itemView.findViewById(R.id.home);
tv_office = (TextView) itemView.findViewById(R.id.tv_office);
}
}
}
活动主布局(_M)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/card_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
卡片布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_marginRight="15dp"
android:layout_marginTop="5dp"
card_view:cardCornerRadius="6dp"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="2dp"
android:orientation="vertical">
<TextView
android:id="@+id/tv_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:textColor="@color/design_default_color_on_primary"
android:textStyle="bold"
android:textSize="18sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_name"
android:textSize="16sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_email"
android:textSize="16sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_address"
android:textSize="16sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_gender"
android:textSize="16sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_mobile"
android:textSize="16sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_home"
android:textSize="16sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_office"
android:textSize="16sp"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
grad尔
plugins {
id 'com.android.application'
}
android {
compileSdk 30
defaultConfig {
applicationId "com.example.retrofitnested"
minSdk 26
targetSdk 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_6
targetCompatibility JavaVersion.VERSION_1_6
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation "androidx.recyclerview:recyclerview:1.2.1"
// For control over item selection of both touch and mouse driven selection
implementation "androidx.recyclerview:recyclerview-selection:1.1.0"
implementation "androidx.cardview:cardview:1.0.0"
}
信息清单档案
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.retrofitnested">
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.RetrofitNested">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
日志目录
2021-09-07 07:32:45.859 9923-9923/com.example.retrofitnested D/NetworkSecurityConfig: No Network Security Config specified, using platform default
2021-09-07 07:32:45.861 9923-9923/com.example.retrofitnested D/NetworkSecurityConfig: No Network Security Config specified, using platform default
2021-09-07 07:32:43.046 9923-9923/? I/.retrofitneste: Late-enabling -Xcheck:jni
2021-09-07 07:32:43.086 9923-9923/? I/.retrofitneste: Unquickening 12 vdex files!
2021-09-07 07:32:43.089 9923-9923/? W/.retrofitneste: Unexpected CPU variant for X86 using defaults: x86
at auct.a(:com.google.android.gms@201817022@20.18.17 (040700-311416286):22)
at anen.a(:com.google.android.gms@201817022@20.18.17 (040700-311416286):19)
2021-09-07 07:32:43.046 9923-9923/? I/.retrofitneste: Late-enabling -Xcheck:jni
2021-09-07 07:32:43.086 9923-9923/? I/.retrofitneste: Unquickening 12 vdex files!
2021-09-07 07:32:43.089 9923-9923/? W/.retrofitneste: Unexpected CPU variant for X86 using defaults: x86
2021-09-07 07:32:45.859 9923-9923/com.example.retrofitnested D/NetworkSecurityConfig: No Network Security Config specified, using platform default
2021-09-07 07:32:43.046 9923-9923/? I/.retrofitneste: Late-enabling -Xcheck:jni
2021-09-07 07:32:43.086 9923-9923/? I/.retrofitneste: Unquickening 12 vdex files!
2021-09-07 07:32:43.089 9923-9923/? W/.retrofitneste: Unexpected CPU variant for X86 using defaults: x86
2021-09-07 07:32:45.859 9923-9923/com.example.retrofitnested D/NetworkSecurityConfig: No Network Security Config specified, using platform default
2021-09-07 07:32:47.205 9923-9959/com.example.retrofitnested D/libEGL: loaded /vendor/lib/egl/libEGL_emulation.so
2021-09-07 07:32:47.359 9923-9959/com.example.retrofitnested D/libEGL: loaded /vendor/lib/egl/libGLESv1_CM_emulation.so
2021-09-07 07:32:47.502 9923-9959/com.example.retrofitnested D/libEGL: loaded /vendor/lib/egl/libGLESv2_emulation.so
2021-09-07 07:32:47.948 9923-9923/com.example.retrofitnested W/.retrofitneste: Verification of androidx.lifecycle.LifecycleEventObserver androidx.lifecycle.Lifecycling.lifecycleEventObserver(java.lang.Object) took 152.030ms (795.89 bytecodes/s) (2432B approximate peak alloc)
2021-09-07 07:32:48.467 9923-9923/com.example.retrofitnested W/.retrofitneste: Verification of void androidx.core.util.Preconditions.checkArgument(boolean) took 153.953ms (58.46 bytecodes/s) (896B approximate peak alloc)
2021-09-07 07:32:49.768 9923-9923/com.example.retrofitnested W/.retrofitneste: Verification of void androidx.appcompat.R$layout.<init>() took 112.475ms (35.56 bytecodes/s) (736B approximate peak alloc)
2021-09-07 07:32:49.867 9923-9923/com.example.retrofitnested I/.retrofitneste: IncrementDisableThreadFlip blocked for 95.648ms
2021-09-07 07:32:50.833 9923-9923/com.example.retrofitnested W/.retrofitneste: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (greylist, reflection, allowed)
2021-09-07 07:32:50.835 9923-9923/com.example.retrofitnested W/.retrofitneste: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (greylist, reflection, allowed)
2021-09-07 07:32:51.648 9923-9923/com.example.retrofitnested W/.retrofitneste: Accessing hidden method Ljava/lang/invoke/MethodHandles$Lookup;-><init>(Ljava/lang/Class;I)V (greylist, reflection, allowed)
2021-09-07 07:32:52.119 9923-9923/com.example.retrofitnested W/.retrofitneste: Accessing hidden method Ldalvik/system/CloseGuard;->get()Ldalvik/system/CloseGuard; (greylist,core-platform-api, reflection, allowed)
2021-09-07 07:32:52.120 9923-9923/com.example.retrofitnested W/.retrofitneste: Accessing hidden method Ldalvik/system/CloseGuard;->open(Ljava/lang/String;)V (greylist,core-platform-api, reflection, allowed)
2021-09-07 07:32:52.120 9923-9923/com.example.retrofitnested W/.retrofitneste: Accessing hidden method Ldalvik/system/CloseGuard;->warnIfOpen()V (greylist,core-platform-api, reflection, allowed)
2021-09-07 07:32:52.792 9923-9972/com.example.retrofitnested W/.retrofitneste: Verification of boolean okhttp3.internal.connection.RouteSelector.hasNextProxy() took 132.199ms (105.90 bytecodes/s) (960B approximate peak alloc)
2021-09-07 07:32:53.616 9923-9958/com.example.retrofitnested D/HostConnection: HostConnection::get() New Host Connection established 0xf26e2f30, tid 9958
2021-09-07 07:32:53.671 9923-9923/com.example.retrofitnested W/RecyclerView: No adapter attached; skipping layout
2021-09-07 07:32:53.698 9923-9958/com.example.retrofitnested D/HostConnection: HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 ANDROID_EMU_YUV_Cache ANDROID_EMU_async_unmap_buffer ANDROID_EMU_has_shared_slots_host_memory_allocator ANDROID_EMU_sync_buffer_data GL_OES_EGL_image_external_essl3 GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_host_side_tracing ANDROID_EMU_async_frame_commands ANDROID_EMU_gles_max_version_3_0
2021-09-07 07:32:53.846 9923-9958/com.example.retrofitnested D/EGL_emulation: eglCreateContext: 0xf26e1e20: maj 3 min 0 rcv 3
2021-09-07 07:32:53.852 9923-9958/com.example.retrofitnested D/EGL_emulation: eglMakeCurrent: 0xf26e1e20: ver 3 0 (tinfo 0xf2a17610) (first time)
2021-09-07 07:32:53.995 9923-9958/com.example.retrofitnested I/Gralloc4: mapper 4.x is not supported
2021-09-07 07:32:54.012 9923-9958/com.example.retrofitnested D/HostConnection: createUnique: call
2021-09-07 07:32:54.015 9923-9958/com.example.retrofitnested D/HostConnection: HostConnection::get() New Host Connection established 0xf26e2360, tid 9958
2021-09-07 07:32:54.017 9923-9958/com.example.retrofitnested D/goldfish-address-space: allocate: Ask for block of size 0x100
2021-09-07 07:32:54.021 9923-9958/com.example.retrofitnested D/goldfish-address-space: allocate: ioctl allocate returned offset 0x38fffe000 size 0x2000
2021-09-07 07:32:54.059 9923-9958/com.example.retrofitnested D/HostConnection: HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 ANDROID_EMU_YUV_Cache ANDROID_EMU_async_unmap_buffer ANDROID_EMU_has_shared_slots_host_memory_allocator ANDROID_EMU_sync_buffer_data GL_OES_EGL_image_external_essl3 GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_host_side_tracing ANDROID_EMU_async_frame_commands ANDROID_EMU_gles_max_version_3_0
2021-09-07 07:32:55.143 9923-9937/com.example.retrofitnested I/.retrofitneste: Background concurrent copying GC freed 2691(167KB) AllocSpace objects, 0(0B) LOS objects, 49% free, 2729KB/5458KB, paused 7.201ms total 885.483ms
2021-09-07 07:32:56.044 9923-9958/com.example.retrofitnested I/OpenGLRenderer: Davey! duration=3338ms; Flags=1, IntendedVsync=6193055405074, Vsync=6193288738398, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=6193303389500, AnimationStart=6193303566800, PerformTraversalsStart=6193303917200, DrawStart=6194443788000, SyncQueued=6194448390800, SyncStart=6194466515800, IssueDrawCommandsStart=6194467068800, SwapBuffers=6195908458000, FrameCompleted=6196411989700, DequeueBufferDuration=627200, QueueBufferDuration=4017500, GpuCompleted=72904454231491230,
2021-09-07 07:32:56.352 9923-9923/com.example.retrofitnested W/.retrofitneste: Verification of androidx.appcompat.view.menu.MenuItemImpl androidx.appcompat.view.menu.MenuBuilder.findItemWithShortcutForKey(int, android.view.KeyEvent) took 196.805ms (528.44 bytecodes/s) (2352B approximate peak alloc)
2021-09-07 07:32:57.432 9923-9923/com.example.retrofitnested I/Choreographer: Skipped 265 frames! The application may be doing too much work on its main thread.
2021-09-07 07:32:57.604 9923-9958/com.example.retrofitnested I/OpenGLRenderer: Davey! duration=4594ms; Flags=0, IntendedVsync=6193372077495, Vsync=6197788743985, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=6197800359900, AnimationStart=6197800549500, PerformTraversalsStart=6197801008300, DrawStart=6197805360500, SyncQueued=6197808308100, SyncStart=6197813106200, IssueDrawCommandsStart=6197813446600, SwapBuffers=6197819007600, FrameCompleted=6197971534600, DequeueBufferDuration=4388800, QueueBufferDuration=28498400, GpuCompleted=43984843964424,
1条答案
按热度按时间h79rfbju1#
您应该将
layoutManager
设置为RecyclerView.在调用loadData()
方法之前放置以下代码:必须在
AndroidManifest.xml
中添加Network security configuration
创建文件res/xml/network_security_config.xml -
AndroidManifest.xml
MainActivity.java
编辑
DataAdapter.java
ApiClient.java