【问题标题】:JSON Request returns nullJSON 请求返回 null
【发布时间】:2017-03-12 17:05:04
【问题描述】:

我在 Android 上使用 Volley 库,但是当我创建 JSONArrayRequest 时,它会自动返回 null。但是如果我继续调试,第二次尝试它会填充数组。这是我的代码:

BackgroundTask.java

public class BackgroundTask{

    Context context;
    ArrayList<Dua> arrayList = new ArrayList<>();
    String json_url = "http://www.burakakyalcin.site/getDua.php";

    public BackgroundTask(Context context){
        this.context = context;
    }

    public ArrayList<Dua> getList(){
        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.POST, json_url, (String)null, new Response.Listener<JSONArray>() {
            @Override
            public void onResponse(JSONArray response) {
                int count = 0;
                while(count<response.length()){
                    try {
                        JSONObject jsonObject = response.getJSONObject(count);
                        Dua dua = new Dua(jsonObject.getString("DuaId"),jsonObject.getString("DuaSender"),jsonObject.getString("DuaHeader"),
                            jsonObject.getString("DuaText"),jsonObject.getString("DuaLike"));
                        arrayList.add(dua);
                        count++;
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(context, error.toString(), Toast.LENGTH_LONG).show();
                error.printStackTrace();
            }
        });
        MySingleton.getInstance(context).addToRequestQueue(jsonArrayRequest);
        return arrayList;
    }

}

MyFragment.java

public class MyFragment extends Fragment{

    RecyclerView recyclerView;
    RecyclerView.Adapter adapter;
    RecyclerView.LayoutManager layoutManager;
    ArrayList<Dua> arrayList = new ArrayList<>();

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_my, container, false);
        recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerview);
        layoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
        recyclerView.setHasFixedSize(true);
        BackgroundTask backgroundTask = new BackgroundTask(getActivity().getApplicationContext());
        arrayList = backgroundTask.getList();
        adapter = new RecyclerAdapter(arrayList);
        recyclerView.setAdapter(adapter);
        return rootView;
    }


}

RecyclerAdapter.java

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {

ArrayList<Dua> arrayList = new ArrayList<>();

public RecyclerAdapter(ArrayList<Dua> arrayList){
    this.arrayList = arrayList;
}


public void setArrayList (ArrayList<Dua> arrayList){
    this.arrayList=arrayList;
    notifyItemRangeChanged(0, arrayList.size());
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_item, parent, false);
    MyViewHolder myViewHolder = new MyViewHolder(view);
    return myViewHolder;
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    holder.DuaSender.setText(arrayList.get(position).getDuaSender());
    holder.DuaHeader.setText(arrayList.get(position).getDuaHeader());
    holder.DuaLike.setText(arrayList.get(position).getDuaLike());
}

@Override
public int getItemCount() {
    return arrayList.size();
}

public static class MyViewHolder extends RecyclerView.ViewHolder{

    TextView DuaHeader, DuaSender, DuaLike;

    public MyViewHolder(View itemView) {
        super(itemView);
        DuaHeader = (TextView) itemView.findViewById(R.id.duaHeaderRec);
        DuaSender = (TextView) itemView.findViewById(R.id.duaSenderRec);
        DuaLike = (TextView) itemView.findViewById(R.id.duaLikeRec);
    }
}
}

【问题讨论】:

  • 你确定它在你第一次调用时返回 null,而不是一个空列表吗?
  • @AlexeySoshin 是的,它返回空列表

标签: java android mysql android-fragments android-volley


【解决方案1】:

JsonArrayRequest 是异步的。

当你打电话时

arrayList = backgroundTask.getList();

首先你会得到一个空列表:

ArrayList<Dua> arrayList = new ArrayList<>();

并且只有在 HTTP 调用成功后,才会被填充。所以,基本上你需要在使用它之前等待你的结果。

public class BackgroundTask{

Context context;
Fragment fragment;
ArrayList<Dua> arrayList = new ArrayList<>();
String json_url = "http://www.burakakyalcin.site/getDua.php";

public BackgroundTask(Context context, MyFragment fragment){
    this.context = context;
    this.fragment = fragment;
}

public void getList(){
    JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.POST, json_url, (String)null, new Response.Listener<JSONArray>() {
        @Override
        public void onResponse(JSONArray response) {
               // Map the JSON as you did before

               // Call your fragment
               fragment.setList(arrayList);
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Toast.makeText(context, error.toString(), Toast.LENGTH_LONG).show();
            error.printStackTrace();
        }
    });

    MySingleton.getInstance(context).addToRequestQueue(jsonArrayRequest);
}

在您的片段中,您需要一个 setter 方法。只有当它被调用时,你才应该渲染列表:

public class MyFragment extends Fragment{
RecyclerView recyclerView;
RecyclerView.Adapter adapter;
RecyclerView.LayoutManager layoutManager;
ArrayList<Dua> arrayList = new ArrayList<>();
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_my, container, false);


    recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerview);
    layoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
    recyclerView.setHasFixedSize(true);

    BackgroundTask backgroundTask = new BackgroundTask(getActivity().getApplicationContext(), this);


    return rootView;
}

public void setList(List<Dua> list) {
    adapter = new RecyclerAdapter(list);
    recyclerView.setAdapter(adapter);
}

}

【讨论】:

  • 谢谢好点,但我仍然有错误,当我第一次发出 JSON 数组请求时,它会自动跳转到返回空数组列表,甚至不去 onError 或 onResponse 方法。它在 Fragment 中返回 rootview 后填充数组。填满后,什么也没有发生。
  • 您的代码中不应包含任何“返回数组列表”。请再次检查我的示例,并尝试将其集成到您的解决方案中。
  • 现在我收到“E/RecyclerView:未连接适配器;跳过布局”错误。我已将我的 RecyclerAdapter 类添加到问题中
  • 我认为你应该为 RecyclerView 提出一个新问题,因为这个问题是关于 API 调用的。
  • 顺便说一句,在这段代码中我们不调用 BackgroundTask 的 getList() 方法吗?为什么?
猜你喜欢
  • 1970-01-01
  • 2020-06-13
  • 1970-01-01
  • 2017-11-26
  • 2011-05-30
  • 2019-08-26
  • 2016-03-31
  • 2023-03-07
  • 1970-01-01
相关资源
最近更新 更多