简体   繁体   中英

How to set data to listview using Retrofit?

Firstly This is code. But this is not real code.

API_Interface.java

public interface API_Interface{
    @GET("/api/foo")
    Call<Foo> foo_API();
}

foo.java

public class foo{
    @SerializedName("foo")
    @Expose
    private String foo;

    public String getFoo() {
        return foo;
    }

    public void setFoo(String foo) {
        this.foo = foo;
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity{
    String buzz;
    Retrofit foo_retro;

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

        ListView listView = (ListView) findViewById(R.id.list_view);
        ArrayList<foo> fooList = new ArrayList<foo>();
        FooAdapter fooAdapter = new FooAdapter(this, 0, fooList);
        listView.setAdapter(fooAdapter);

        ...

        foo_retro = new Retrofit.Builder()
                .baseUrl("http://api.foo.com")
                .addConverterFactory(GsonConverterFactory.create())
                .build();  

        API_Interface foo_service = foo_retro.create(API_Interface.class)

        Call<foo> foo_call=foo_service.foo_API();
        foo_call.enqueue(new Callback<foo>() {             
            @Override
            public void onResponse(Call<foo> call, Response<foo> response) {
                buzz = response.body().getFoo();
                System.out.println(buzz);
            } 

            @Override
            public void onFailure(Call<zaifExchange> call, Throwable t) {
                Toast.makeText(MainActivity.this, "Error", Toast.LENGTH_SHORT);
            }
        });
        fooList.add(new foo(buzz));
        System.out.println(buzz);
    }
}

When I run this code, I can get and print buzz (like "Apple") in the onResponse method. However, I can't set data to listview ( buzz is null). I know the reason is that enqueue is asynchronous, so the terminal shows:

I/System.out: null
I/System.out: Apple

So what should I do? Thanks.

Add response into fooList inside onResponse otherwise you are adding null values as

@Override
public void onResponse(Call<foo> call, Response<foo> response) {
    buzz = response.body().getFoo();
    fooList.add(new foo(buzz));
    System.out.println(buzz);
    fooAdapter.notifyDataSetChanged();
   // ^^^^ notify changes to display data 
   // you might want to declare references outside oncreate to avoid local variables
} 

remove

fooList.add(new foo(buzz));
System.out.println(buzz);

(outside enqueue )because before response buzz will be null

As I see it, your problem is twofold:

  1. Consider adding in a delay before you print in the onCreate() method, itself. Better yet, verify that buzz has actually been set before continuing.
  2. Because enqueue() is asynchronous, no matter happens, buzz will likely not be seen by the parent thread that does the printing. Instead, consider wrapping the buzz field using the AtomicReference class. That way, regardless of the thread, the most up-to-date value of buzz will be seen by any thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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