如何在执行下一行之前等待凌空响应结束



我正在开发一个从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;
    }
}

知道吗?谢谢。

该方法

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

泛型回调:

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

方法getLevels将是无效的,并且带有回调参数

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...
            }
      }
);

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

我建议在您的情况下保留一个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);
}

希望有帮助。

最新更新