JSON 解析的问题
Troubles with JSON parsing
我正在开发一个简单的新闻应用程序。
我需要以 JSON 格式从远程服务器获取数据,然后将其放在视图中。我使用 TabLayout 和 recyclerView 来显示数据类别,并使用 Volley 来查询 no API here.
TabLayout 是根据 JSON 中的数据自动设置的,我在其中提取标签标题,每个标签的内容都显示在 recyclerView 上(文章标题、图像、内容、链接...)并呈现在片段内
我花了几个小时试图调试它但没有成功。但是无论我做什么,都没有显示任何数据。不确定我做错了什么。
我知道这里不适合提出此类问题,但我有点绝望,需要一些经验丰富的开发人员来查看我的问题。
工作原理:
Activity 启动 BaseArticleFragment,它调用加载内容类别并将数据绑定到视图的方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.fm = getSupportFragmentManager();
this.baseArticleFragment = new BaseArticleFragment();
FragmentTransaction ft = this.fm.beginTransaction();
ft.add(R.id.fragment_container, this.baseArticleFragment, TAB_LAYOUT_FRAGMENT_TAG);
ft.commit();
}
启动时,baseArticleFragment 在其 onActivityCreated() 方法中调用 loadCategories() 方法:
@Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
loadCategories();
}
这里是 loadCategories() 方法:
private void loadCategories(){
String url = "http://somesite.com/categories"; //link to grab the json data
ApplicationController.getInstance().addToRequestQueue(
new JsonObjectRequest(0, url, null, new Listener<JSONObject>() { //0 is the Volley code for GET method
@Override
public void onResponse(JSONObject jsonObject) {
BaseArticleFragment.categories = JSONParser.parseCategories(jsonObject);
BaseArticleFragment.this.mViewPager.setAdapter(
new RecyclerViewFragmentPagerAdapter(BaseArticleFragment.this.getChildFragmentManager(),
BaseArticleFragment.categories));
BaseArticleFragment.this.mTabLayout.setupWithViewPager(BaseArticleFragment.this.mViewPager);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError vError){
Log.d("BaseArticleFragment", "---Volley Error---");
Snackbar.make(BaseArticleFragment.this.mTabLayout, R.string.error_load_categories, Snackbar.LENGTH_SHORT)
.setAction(R.string.action_retry, new View.OnClickListener() {
@Override
public void onClick(View v) {
BaseArticleFragment.this.loadCategories();
}
}).show();
}
}));
}
我猜问题可能出在查询上,但不确定,因为我认为我的逻辑很好
编辑:
这是我需要获取的 JSON 数据:
[
{
"name": "Topic 1",
"tid": "2",
},
{
"name": "Topic 2",
"tid": "3",
},
{
"name": "Topic 3",
"tid": "4",
},
{
"name": "Topic 4",
"tid": "5",
},
{
"name": "Topic 5",
"tid": "6",
},
{
"name": "Topic 6",
"tid": "1415",
},
{
"name": "Topic 7",
"tid": "1414",
},
{
"name": "Topic 8",
"tid": "1298",
},
{
"name": "Topic 9",
"tid": "1301",
},
{
"name": "Topic 10",
"tid": "1299",
},
{
"name": "Topic 11",
"tid": "1302",
},
{
"name": "Topic 12",
"tid": "1300",
},
{
"name": "Topic 13",
"tid": "1297",
}
]
编辑 2:
我忘记在我的 JSONPARser class
中粘贴 parseCategories() 的代码
public static ArrayList<Category> parseCategories(JSONObject jsonObject) {
ArrayList<Category> categoryArrayList = new ArrayList<>();
try {
JSONArray categories = jsonObject.getJSONArray("categories");
Category all = new Category();
all.setTid("0");
all.setName(ApplicationController.getInstance().getString(R.string.tab_all));
categoryArrayList.add(all);
for (int i = 0; i < categories.length(); i++) {
JSONObject catObject = categories.getJSONObject(i);
Category category = new Category();
category.setTid(catObject.getString("tid"));
category.setName(catObject.getString("name"));
categoryArrayList.add(category);
}
return categoryArrayList;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
检查是否为recyclerView设置了LayoutManager
recyclerView.setLayoutManager(new LinearLayoutManager(MyActivity.this));
我们也可以拥有您的代码和 JSON 数据吗?由于我们无法读取您的想法或计算机上的内容...请对您的 post 进行一些编辑,添加代码和 json 数据,以便我们可以帮助您。
你忘了在"load"方法的末尾添加这个东西:
Volley.newRequestQueue(this).add(jsonRequest);
尝试添加它...
不要使用new RequestQueue
,请使用RequestQueue jsonQueue = new RequestQueue
像这样:
RequestQueue requestQueue = Volley.newRequestQueue(this);
String url = "https://someurl.com/api";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(url, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
JSONArray ja = new JSONArray(response);
for(int i = 0; i < ja.length(); i++)
{
JSONObject jo = ja.get(i);
String name = jo.getString("name");
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("LOG", error.toString());
}
});
requestQueue.add(jsonObjectRequest);
试试这个@esQmo_,
StringRequest stringRequest = new StringRequest(url , new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
ArrayList<Hashmap<String,String>> arraylist = new
ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
HashMap<String, String> hashMap = new HashMap<>();
String name =
jsonArray.getJSONObject(i).getString("name");
String tid =
jsonArray.getJSONObject(i).getString("tid");
hashMap.put("name", name);
hashMap.put("tid ", tid );
arraylist.add(hashMap);
Log.e("response",name + "\n" + tid);
}
attachAdapter(arraylist);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue queue = Volley.newRequestQueue(this);
queue.add(stringRequest);
//setting adapter data to the RecyclerView
private void attachAdapter(ArrayList<HashMap<String, String>>
arrayList) {
ExampleAdapter adapter = new ExampleAdapter(arrayList,this);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
这是适配器class
public class ExampleAdpater extends RecyclerView.Adapter<ExampleAdpater.ExampleViewHolder>{
public ArrayList<HashMap<String,String>> arraylist;
public Context context;
public ExampleAdpater(ArrayList<HashMap<String, String>> arraylist, Context context) {
this.arraylist= arraylist;
this.context = context;
}
@NonNull
@Override
public ExampleViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.textLayout,viewGroup,false);
return new ExampleViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ExampleViewHolder viewHolder, int i) {
HashMap<String,String> hashMap = arraylist.get(i);
viewHolder.name.setText(hashMap.get("name"));
viewHolder.tid.setText(hashMap.get("tid"));
}
@Override
public int getItemCount() {
return arraylist.size();
}
public class ExampleViewHolder extends RecyclerView.ViewHolder{
TextView name,tid;
public ExampleViewHolder(@NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.name);
tid = itemView.findViewById(R.id.tid);
name.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(v.getContext(), ""+name.getText().toString(),
Toast.LENGTH_SHORT).show();
}
});
}
}
}
textLayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/name"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tid"
/>
</LinearLayout>
由于您收到超时错误,您可以更改超时值,以便等待更长时间。
尝试这样的事情:
jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(
MY_SOCKET_TIMEOUT_MS,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
其中 MY_SOCKET_TIMEOUT_MS 是您希望在超时前等待的时间量(以毫秒为单位)。从 5000(5 秒)开始并尝试一下。
在
之前执行此操作
requestQueue.add(jsonObjectRequest);
我正在开发一个简单的新闻应用程序。 我需要以 JSON 格式从远程服务器获取数据,然后将其放在视图中。我使用 TabLayout 和 recyclerView 来显示数据类别,并使用 Volley 来查询 no API here.
TabLayout 是根据 JSON 中的数据自动设置的,我在其中提取标签标题,每个标签的内容都显示在 recyclerView 上(文章标题、图像、内容、链接...)并呈现在片段内
我花了几个小时试图调试它但没有成功。但是无论我做什么,都没有显示任何数据。不确定我做错了什么。
我知道这里不适合提出此类问题,但我有点绝望,需要一些经验丰富的开发人员来查看我的问题。
工作原理:
Activity 启动 BaseArticleFragment,它调用加载内容类别并将数据绑定到视图的方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.fm = getSupportFragmentManager();
this.baseArticleFragment = new BaseArticleFragment();
FragmentTransaction ft = this.fm.beginTransaction();
ft.add(R.id.fragment_container, this.baseArticleFragment, TAB_LAYOUT_FRAGMENT_TAG);
ft.commit();
}
启动时,baseArticleFragment 在其 onActivityCreated() 方法中调用 loadCategories() 方法:
@Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
loadCategories();
}
这里是 loadCategories() 方法:
private void loadCategories(){
String url = "http://somesite.com/categories"; //link to grab the json data
ApplicationController.getInstance().addToRequestQueue(
new JsonObjectRequest(0, url, null, new Listener<JSONObject>() { //0 is the Volley code for GET method
@Override
public void onResponse(JSONObject jsonObject) {
BaseArticleFragment.categories = JSONParser.parseCategories(jsonObject);
BaseArticleFragment.this.mViewPager.setAdapter(
new RecyclerViewFragmentPagerAdapter(BaseArticleFragment.this.getChildFragmentManager(),
BaseArticleFragment.categories));
BaseArticleFragment.this.mTabLayout.setupWithViewPager(BaseArticleFragment.this.mViewPager);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError vError){
Log.d("BaseArticleFragment", "---Volley Error---");
Snackbar.make(BaseArticleFragment.this.mTabLayout, R.string.error_load_categories, Snackbar.LENGTH_SHORT)
.setAction(R.string.action_retry, new View.OnClickListener() {
@Override
public void onClick(View v) {
BaseArticleFragment.this.loadCategories();
}
}).show();
}
}));
}
我猜问题可能出在查询上,但不确定,因为我认为我的逻辑很好
编辑:
这是我需要获取的 JSON 数据:
[
{
"name": "Topic 1",
"tid": "2",
},
{
"name": "Topic 2",
"tid": "3",
},
{
"name": "Topic 3",
"tid": "4",
},
{
"name": "Topic 4",
"tid": "5",
},
{
"name": "Topic 5",
"tid": "6",
},
{
"name": "Topic 6",
"tid": "1415",
},
{
"name": "Topic 7",
"tid": "1414",
},
{
"name": "Topic 8",
"tid": "1298",
},
{
"name": "Topic 9",
"tid": "1301",
},
{
"name": "Topic 10",
"tid": "1299",
},
{
"name": "Topic 11",
"tid": "1302",
},
{
"name": "Topic 12",
"tid": "1300",
},
{
"name": "Topic 13",
"tid": "1297",
}
]
编辑 2: 我忘记在我的 JSONPARser class
中粘贴 parseCategories() 的代码 public static ArrayList<Category> parseCategories(JSONObject jsonObject) {
ArrayList<Category> categoryArrayList = new ArrayList<>();
try {
JSONArray categories = jsonObject.getJSONArray("categories");
Category all = new Category();
all.setTid("0");
all.setName(ApplicationController.getInstance().getString(R.string.tab_all));
categoryArrayList.add(all);
for (int i = 0; i < categories.length(); i++) {
JSONObject catObject = categories.getJSONObject(i);
Category category = new Category();
category.setTid(catObject.getString("tid"));
category.setName(catObject.getString("name"));
categoryArrayList.add(category);
}
return categoryArrayList;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
检查是否为recyclerView设置了LayoutManager
recyclerView.setLayoutManager(new LinearLayoutManager(MyActivity.this));
我们也可以拥有您的代码和 JSON 数据吗?由于我们无法读取您的想法或计算机上的内容...请对您的 post 进行一些编辑,添加代码和 json 数据,以便我们可以帮助您。
你忘了在"load"方法的末尾添加这个东西:
Volley.newRequestQueue(this).add(jsonRequest);
尝试添加它...
不要使用new RequestQueue
,请使用RequestQueue jsonQueue = new RequestQueue
像这样:
RequestQueue requestQueue = Volley.newRequestQueue(this);
String url = "https://someurl.com/api";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(url, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
JSONArray ja = new JSONArray(response);
for(int i = 0; i < ja.length(); i++)
{
JSONObject jo = ja.get(i);
String name = jo.getString("name");
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("LOG", error.toString());
}
});
requestQueue.add(jsonObjectRequest);
试试这个@esQmo_,
StringRequest stringRequest = new StringRequest(url , new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
ArrayList<Hashmap<String,String>> arraylist = new
ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
HashMap<String, String> hashMap = new HashMap<>();
String name =
jsonArray.getJSONObject(i).getString("name");
String tid =
jsonArray.getJSONObject(i).getString("tid");
hashMap.put("name", name);
hashMap.put("tid ", tid );
arraylist.add(hashMap);
Log.e("response",name + "\n" + tid);
}
attachAdapter(arraylist);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue queue = Volley.newRequestQueue(this);
queue.add(stringRequest);
//setting adapter data to the RecyclerView
private void attachAdapter(ArrayList<HashMap<String, String>>
arrayList) {
ExampleAdapter adapter = new ExampleAdapter(arrayList,this);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
这是适配器class
public class ExampleAdpater extends RecyclerView.Adapter<ExampleAdpater.ExampleViewHolder>{
public ArrayList<HashMap<String,String>> arraylist;
public Context context;
public ExampleAdpater(ArrayList<HashMap<String, String>> arraylist, Context context) {
this.arraylist= arraylist;
this.context = context;
}
@NonNull
@Override
public ExampleViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.textLayout,viewGroup,false);
return new ExampleViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ExampleViewHolder viewHolder, int i) {
HashMap<String,String> hashMap = arraylist.get(i);
viewHolder.name.setText(hashMap.get("name"));
viewHolder.tid.setText(hashMap.get("tid"));
}
@Override
public int getItemCount() {
return arraylist.size();
}
public class ExampleViewHolder extends RecyclerView.ViewHolder{
TextView name,tid;
public ExampleViewHolder(@NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.name);
tid = itemView.findViewById(R.id.tid);
name.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(v.getContext(), ""+name.getText().toString(),
Toast.LENGTH_SHORT).show();
}
});
}
}
}
textLayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/name"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tid"
/>
</LinearLayout>
由于您收到超时错误,您可以更改超时值,以便等待更长时间。
尝试这样的事情:
jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(
MY_SOCKET_TIMEOUT_MS,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
其中 MY_SOCKET_TIMEOUT_MS 是您希望在超时前等待的时间量(以毫秒为单位)。从 5000(5 秒)开始并尝试一下。
在
之前执行此操作requestQueue.add(jsonObjectRequest);