解析GSON - 怎么样?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解析GSON - 怎么样?相关的知识,希望对你有一定的参考价值。

我有一个显示加密货币价格的应用程序。我有活动调用api类来检索大型JSON数据。

这是价格活动类。

public class PriceActivity extends AppCompatActivity {

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

        ApiCall apiCall = new ApiCall(this, "https://api.coinmarketcap.com/v1/ticker/?convert=EUR");

        RecyclerView customView = (RecyclerView) findViewById(R.id.recyclerviewprice);
        CoinAdapter CoinAdapter = new CoinAdapter(apiCall.coins, this);
        customView.setLayoutManager(new LinearLayoutManager(this));
        customView.setAdapter(CoinAdapter);
        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setTitle("Links");
    }
}

这是api类

public class ApiCall {
    private Context mcontext;
    private String URL;
    public static List<Coin> coins;

    public ApiCall(Context mcontext, String URL) {
        this.mcontext = mcontext;
        this.URL = URL;
        connect(mcontext);
    }

    public void connect(Context mcontext) {
        RequestQueue requestQueue = Volley.newRequestQueue(mcontext);
        StringRequest objectRequest = new StringRequest(
                Request.Method.GET,
                URL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {

                        GsonBuilder builder = new GsonBuilder();
                        Gson gson = builder.create();

                        coins = Arrays.asList(gson.fromJson(response, Coin[].class));

                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.i(TAG, "onResponse: ");
                    }
                }
        );

        requestQueue.add(objectRequest);
    }
}

问题是,价格活动类不会等到api类完成。我该如何解决这个问题?或者我如何正确解析大数据?

答案

这是因为你的Activity在主线程中运行,而API是在一个单独的线程中调用的。 Activity执行不会等待API调用完成。处理这种情况的正确方法是通知调用活动API已经到达的结果。

要实现这种行为,您需要实现这样的接口。

public interface HttpResponseListener {
    void httpResponseReceiver(List<Coin> result);
}

现在,你需要在你的HttpResponseListener类中有一个ApiCall实例,需要在构造函数中初始化。因此修改后的ApiCall类应该是这样的。

public class ApiCall {
    private Context mcontext;
    private String URL;
    public static List<Coin> coins;
    public HttpResponseListener mHttpResponseListener;

    public ApiCall(Context mcontext, String URL, HttpResponseListener listener) {
        this.mcontext = mcontext;
        this.URL = URL;
        this.mHttpResponseListener = listener;  // Initialize
        connect(mcontext);
    }

    public void connect(Context mcontext) {
        RequestQueue requestQueue = Volley.newRequestQueue(mcontext);
        StringRequest objectRequest = new StringRequest(
                Request.Method.GET,
                URL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        GsonBuilder builder = new GsonBuilder();
                        Gson gson = builder.create();
                        coins = Arrays.asList(gson.fromJson(response, Coin[].class));
                        mHttpResponseListener.httpResponseReceiver(coins);
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.i(TAG, "onResponse: ");
                    }
                }
        );

        requestQueue.add(objectRequest);
    }
}

现在从你的Activity,你需要听你要在Activity中实现的接口的回调函数。

public class PriceActivity extends AppCompatActivity implements HttpResponseListener {

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

        // Modify the call to support the constructor
        ApiCall apiCall = new ApiCall(this, "https://api.coinmarketcap.com/v1/ticker/?convert=EUR", this);

        RecyclerView customView = (RecyclerView) findViewById(R.id.recyclerviewprice);
        CoinAdapter CoinAdapter = new CoinAdapter(apiCall.coins, this);
        customView.setLayoutManager(new LinearLayoutManager(this));
        customView.setAdapter(CoinAdapter);

        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setTitle("Links");
    }

    // Implement the overriden function
    @Override
    public void httpResponseReceiver(List<Coin> result) {
        // Do something with the list of coins here.
    }
}

希望能解决你的问题。

另一答案

将API调用逻辑放在Adapter类中,并从onResume方法启动请求:

public class PriceActivity extends AppCompatActivity {

    [...]

    @Override
    protected void onResume() {
        super.onResume();
        this.coinAdapter.reload();
    }

}

public class CoinAdapter extends [...] {

    [...]
    List<Coin> coins = new ArrayList<>(0); // empty on start
    Context ctx;

    public CoinAdapter(Context ctx){
        this.ctx = ctx;
    }  

    public void reload() {
        RequestQueue requestQueue = Volley.newRequestQueue(this.ctx);
        StringRequest objectRequest = new StringRequest(
                Request.Method.GET,
                URL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {

                        GsonBuilder builder = new GsonBuilder();
                        Gson gson = builder.create();

                        coins = Arrays.asList(gson.fromJson(response, Coin[].class));

                        // refresh UI
                        notifyDataSetChanged();

                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.i(TAG, "onResponse: ");
                    }
                }
        );

        requestQueue.add(objectRequest);
    }

}

不要忘记从notifyDataSetChanged调用onResponse来刷新UI

以上是关于解析GSON - 怎么样?的主要内容,如果未能解决你的问题,请参考以下文章

java怎么使用gson解析json字符串

gson怎么解析数组和空数组?

android使用gson解析嵌套复杂的json数据,数据怎么显示到布局上,布局怎么写

使用gson解析怎么将json字符串解析为数组

gson解析json集合怎么去除属性

解析GSON - 怎么样?