简体   繁体   English

如何使用Retrofit将数据设置为listview?

[英]How to set data to listview using Retrofit?

Firstly This is code. 首先这是代码。 But this is not real code. 但这不是真正的代码。

API_Interface.java API_Interface.java

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

foo.java 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 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. 当我运行此代码时,我可以在onResponse方法中获取并打印buzz (如“Apple”)。 However, I can't set data to listview ( buzz is null). 但是,我无法将数据设置为listviewbuzz为null)。 I know the reason is that enqueue is asynchronous, so the terminal shows: 我知道原因是enqueue是异步的,所以终端显示:

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 将响应添加到fooList内的onResponse否则您将添加null值作为

@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 (在enqueue之外)因为在响应之前buzz将为null

As I see it, your problem is twofold: 在我看来,你的问题是双重的:

  1. Consider adding in a delay before you print in the onCreate() method, itself. 考虑在onCreate()方法本身打印之前添加延迟。 Better yet, verify that buzz has actually been set before continuing. 更好的是,在继续之前验证是否已实际设置了buzz
  2. Because enqueue() is asynchronous, no matter happens, buzz will likely not be seen by the parent thread that does the printing. 因为enqueue()是异步的,所以无论发生什么,打印的父线程都可能看不到buzz Instead, consider wrapping the buzz field using the AtomicReference class. 相反,请考虑使用AtomicReference类包装buzz字段。 That way, regardless of the thread, the most up-to-date value of buzz will be seen by any thread. 这样,无论线程如何,任何线程都可以看到最新的buzz值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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