如何在执行下一行之前等待Volley响应结束?

时间:2018-03-03 00:32:36

标签: android android-volley

我正在开发一个从API读取数据的Android应用程序,然后在多选对话框中显示这些数据。但是,当我单击该按钮时,该对话框为空。我想也许程序在volley返回响应之前执行下一行代码。我搜索了很多,但我不明白如何解决这个问题,我是初学者使用Volley。

以下是从API获取数据的对话框代码:

public class LevelsDialog extends DialogFragment {
    ArrayList<String> list = new ArrayList<>();
    static   String[] array;
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        array = getLevels();
        final boolean[] checkedItems = new boolean[array.length];
        builder.setTitle("Select Levels").setMultiChoiceItems(array, checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                if(isChecked) {
                    list.add(array[which]);
                    checkedItems[which] =true;
                } else if(list.contains(array[which])) {
                    list.remove(array[which]);
                    checkedItems[which] = false;
                }
            }

        }).setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                for(int i=0 ; i<list.size(); i++)
                Log.e("After", "onClick: "+ list.get(i) );
            }
        });

        return builder.create();
    }

    public String[] getLevels() {
        final ArrayList<String> LevelsList = new ArrayList<>();

        String url = Connection.URL + "/getAllLevels";

        JsonArrayRequest objectRequest = new JsonArrayRequest(
                Request.Method.GET,
                url,
                null,
                new Response.Listener<JSONArray>() {

                    @Override
                    public void onResponse(JSONArray response) {
                        if (response.length() != 0) {
                            int length = response.length();

                            for (int i = 0; i < length; i++) {
                                try {
                                    LevelsList.add(response.get(i).toString());

                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                },
                new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.e("Rest Response Error ", error.toString());
                    }
                });
        Connection.getConnection(getActivity()).addToRequestQueue(objectRequest);

        String[] Levels = LevelsList.toArray(new String[LevelsList.size()]);

        return Levels;
    }
}

有什么想法吗?感谢。

2 个答案:

答案 0 :(得分:0)

您需要等待从您的截击请求中接收数据,然后允许用户点击多选对话框。

我建议在您的案例中保留一个ProgressDialog,这将在收到级别数据之前显示。因此,您的onCreateDialog将会看起来像这样。

private ProgressDialog pD;
private final boolean[] checkedItems;

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {

    pD = new ProgressDialog(context); 
    pD.setMessage("Getting the levels information");

    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setTitle("Select Levels").setMultiChoiceItems(array, checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which, boolean isChecked) {
            if(isChecked) {
                list.add(array[which]);
                checkedItems[which] =true;
            } else if(list.contains(array[which])) {
                list.remove(array[which]);
                checkedItems[which] = false;
            }
        }

    }).setPositiveButton("OK", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            for(int i=0 ; i<list.size(); i++)
            Log.e("After", "onClick: "+ list.get(i) );
        }
    });


    getLevels();
    pD.show(); // Start showing the progress dialog

    return builder.create();
}

现在像这样修改你的getLevels功能。

 public void getLevels() {
    final ArrayList<String> LevelsList = new ArrayList<>();

    String url = Connection.URL + "/getAllLevels";
    JsonArrayRequest objectRequest = new JsonArrayRequest(
            Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
                @Override
                public void onResponse(JSONArray response) {
                    if (response.length() != 0) {
                        int length = response.length();
                        array = new int[length]; // Re-initialize the array

                        for (int i = 0; i < length; i++) {
                            try {
                                array[i] = response.get(i).toString();
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }

                        pD.cancel();
                        checkedItems = new boolean[array.length];
                    }
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.e("Rest Response Error ", error.toString());
                }
            });
    Connection.getConnection(getActivity()).addToRequestQueue(objectRequest);
}

希望有所帮助。

答案 1 :(得分:0)

方法public String[] getLevels()无法立即返回数组,因为你正在向互联网发出请求(这需要时间),因此,你需要使用回调接口,当凌空完成请求时,它将它回拨,只有在这个时候你才会在屏幕上写下

通用回调:

public interface ICallback<T> {
    void onSucess(T result);
    void onError(int code);
}

方法getLevels将为void,并带有回调参数

public void getLevels(final ICallback<String[]> callback) {
    String url = Connection.URL + "/getAllLevels";

    JsonArrayRequest objectRequest = new JsonArrayRequest(
            Request.Method.GET,
            url,
            null,
            new Response.Listener<JSONArray>() {

                @Override
                public void onResponse(JSONArray response) {
                    final ArrayList<String> LevelsList = new ArrayList<>();
                    if (response.length() != 0) {
                        int length = response.length();

                        for (int i = 0; i < length; i++) {
                            try {
                                LevelsList.add(response.get(i).toString());

                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    String[] Levels = LevelsList.toArray( 
                                              new String[LevelsList.size()]);
                    callback.onSucess(Levels); //<-------- CALL IT BACK
                }
            },
            new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.e("Rest Response Error ", error.toString());
                    int code = -1;
                    if(error!=null){
                         if(error.networkResponse!=null){
                              code = error.networkResponse.statusCode;
                         }
                    }
                    callback.onError(code); // <-- ERROR
                }
            });
    Connection.getConnection(getActivity()).addToRequestQueue(objectRequest);

}

因此,您只能在回调中获得级别:

getLevels(
      new ICallback<String[]>(){
            @Override
            public void onSucess(String[] result) {
                  // Create or update the dialog here...
            }
            @Override
            public void onError(int errorCode) {
                  //error treatment...
            }
      }
);