解析 JSON 数据时不显示任何内容

Nothing displays on parsing JSON data

我正在尝试解析来自 https://newsapi.orgJSON 数据并将其显示在应用程序的 recyclerview 上。下面给出了 JSON 数据的示例:

 {
"status": "ok",
"totalResults": 10,
"articles": [
{
"source": {
"id": "google-news",
"name": "Google News"
},
"author": "Kanga Kong",
"title": "Kim Jong Un Sends Right-Hand Man to U.S. for Pre-Summit Talks",
"description": "North Korean leader Kim Jong Un has dispatched one of his top aides to the U.S. for talks ahead of his planned summit with Donald Trump next month, according to a person familiar with the issue who asked not to be named because the trip isn’t public.",
"url": "https://www.bloomberg.com/news/articles/2018-05-29/kim-jong-un-sends-aide-to-u-s-for-pre-summit-talks-yonhap-says",
"urlToImage": "https://assets.bwbx.io/images/users/iqjWHBFdfxIU/i7_b0Umv.ads/v0/1200x802.jpg",
"publishedAt": "2018-05-29T05:42:00+00:00"
},

问题是我无法从给定的 JSON 数据中获取任何数据。代码如下:

MainActivity.java

public class MainActivity extends AppCompatActivity {

private static final String TAG="MainActivity";
private List<Model> modelList;
private RecyclerView recyclerView;
private CustomAdapter customAdapter;

String url="https://newsapi.org/v2/top-headlines?sources=google-news&apiKey=76351c3c06504e12a8c61428162dcf87";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    recyclerView=(RecyclerView)findViewById(R.id.list);
    recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
    customAdapter=new CustomAdapter(MainActivity.this,modelList);
    recyclerView.setAdapter(customAdapter);
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    new DownloadTask().execute(url);
}

public class DownloadTask extends AsyncTask<String,Void,String> {

    private ProgressDialog progressDialog=new ProgressDialog(MainActivity.this);

    @Override
    protected void onPreExecute() {
        progressDialog.setMessage("Loading...");
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    @Override
    protected String doInBackground(String... strings) {
        String result=null;
        StringBuilder response = null;
        //Integer result=0;
        try {
            HttpsURLConnection urlConnection;

            try {
                URL url=new URL(strings[0]);
                urlConnection=(HttpsURLConnection)url.openConnection();
                int statusCode=urlConnection.getResponseCode();

                if (statusCode==HttpsURLConnection.HTTP_OK){
                    BufferedReader br=new BufferedReader(
                            new InputStreamReader(urlConnection.getInputStream()));
                    response=new StringBuilder();
                    String line;
                    while ((line=br.readLine()) !=null) {
                        response.append(line);
                    }
                    parseResult(response.toString());
                    //result=1;
                } /*else {
                result=0;
            }*/
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (final Exception e){
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(getApplicationContext(),
                            "Error",Toast.LENGTH_LONG).show();
                }
            });
        }

        Log.d("ResultForParsing : ",String.valueOf(result));
        Log.d("ResponseForParsing : ",response.toString());
        return result;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        JSONObject mJsonResponse;

        try {
            if (progressDialog!=null)
                progressDialog.dismiss();
        } catch (Exception e){
            e.printStackTrace();
        }

        /*if (integer==1){
            customAdapter=new CustomAdapter(MainActivity.this,modelList);
            recyclerView.setAdapter(customAdapter);
        } else {
            Toast.makeText(getApplicationContext(),"Failed to fetch data",
                    Toast.LENGTH_LONG).show();
        }*/
        parseResult(result);
    }
}

private void parseResult(String result){
    try {
        JSONArray posts=new JSONArray(result);
        modelList=new ArrayList<>();

        for (int i=0;i<posts.length();i++){
            JSONObject post=posts.optJSONObject(i);
            Model item=new Model();
            item.setAuthor(post.optString("author"));
            item.setTitle(post.optString("title"));
            item.setDescription(post.optString("description"));

            modelList.add(item);
            Log.d("AuthorForJSON : ",post.optString("author"));
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
}
}

这里我用了一个Log语句来显示连接是否正常,returns1表示连接成功

CustomAdapter.java

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {

private Context context;
private List<Model> model;

public CustomAdapter(Context context, List<Model> model) {
    this.context = context;
    this.model = model;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    //View view=inflater.inflate(R.layout.row,null);
    View view=LayoutInflater.from(parent.getContext()).inflate(R.layout.row,parent,false);
    ViewHolder holder=new ViewHolder(view);
    return holder;
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {

    //ViewHolder viewHolder=(ViewHolder)holder;
    Model current=model.get(position);
    holder.n_author.setText("Author : "+current.author);
    holder.n_description.setText(current.description);
    holder.n_title.setText(current.title);

    //Picasso.get().load(current.urltoimage).into(n_image);

}

@Override
public int getItemCount() {
    return (null!=model?model.size():0);
}

class ViewHolder extends RecyclerView.ViewHolder {

    TextView n_title;
    TextView n_author;
    ImageView n_image;
    TextView n_description;

    public ViewHolder(View itemView) {
        super(itemView);

        n_title=(TextView)itemView.findViewById(R.id.news_title);
        n_author=(TextView)itemView.findViewById(R.id.news_author);
        n_image=(ImageView)itemView.findViewById(R.id.news_image);
        n_description=(TextView) itemView.findViewById(R.id.news_description);
    }
}
}

Model.java

public class Model {

public String author;
public String title;
public String description;
public String url;
public String urltoimage;
public String published;

public String getAuthor() {
    return author;
}

public void setAuthor(String author) {
    this.author = author;
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public String getUrl() {
    return url;
}

public void setUrl(String url) {
    this.url = url;
}

public String getUrltoimage() {
    return urltoimage;
}

public void setUrltoimage(String urltoimage) {
    this.urltoimage = urltoimage;
}

public String getPublished() {
    return published;
}

public void setPublished(String published) {
    this.published = published;
}
}

目前我只对获取 author 名称、titledescription 感兴趣。

Logcat

    05-29 12:59:15.052 9368-9528/com.example.pritom14.saveeverything I/System.out: [OkHttp] sendRequest<<
05-29 12:59:15.052 9368-9528/com.example.pritom14.saveeverything D/NativeCrypto: ssl=0x7fa58d2780 sslWrite buf=0x7f8f8e8000 len=240 write_timeout_millis=0
    ssl=0x7fa58d2780 sslRead buf=0x7f8f8e8000 len=2048,timeo=0
05-29 12:59:15.377 9368-9528/com.example.pritom14.saveeverything D/NativeCrypto: ssl=0x7fa58d2780 sslRead buf=0x7f8f8e8000 len=2048,timeo=0
05-29 12:59:15.378 9368-9528/com.example.pritom14.saveeverything D/NativeCrypto: ssl=0x7fa58d2780 sslRead buf=0x7f8f8e8000 len=2048,timeo=0
05-29 12:59:15.379 9368-9528/com.example.pritom14.saveeverything D/NativeCrypto: ssl=0x7fa58d2780 sslRead buf=0x7f8f8e8000 len=2048,timeo=0
05-29 12:59:15.394 9368-9528/com.example.pritom14.saveeverything W/System.err: org.json.JSONException: Value {"status":"ok","totalResults":10,"articles":[{"source":{"id":"google-news","name":"Google News"},"author":"https:\/\/www.facebook.com\/bbcnews","title":"Private search for MH370 formally ends","description":"The Malaysia Airlines plane with 239 people disappeared while flying to Beijing from Kuala Lumpur.","url":"http:\/\/www.bbc.com\/news\/world-asia-44285241","urlToImage":"https:\/\/ichef.bbci.co.uk\/news\/1024\/branded_news\/E54A\/production\/_101789685_mediaitem101789684.jpg","publishedAt":"2018-05-29T05:17:22+00:00"},{"source":{"id":"google-news","name":"Google News"},"author":"Analysis by Stephen Collinson, CNN","title":"Trump whips up immigration storm over children","description":"For President Donald Trump, every crisis in America's immigration system is an opportunity.","url":"https:\/\/www.cnn.com\/2018\/05\/29\/politics\/donald-trump-immigration-separated-children\/index.html","urlToImage":"https:\/\/cdn.cnn.com\/cnnnext\/dam\/assets\/180523143703-02-trump-immigration-rountable-05-23-2018-super-tease.jpg","publishedAt":"2018-05-29T05:02:57+00:00"},{"source":{"id":"google-news","name":"Google News"},"author":null,"title":"The Rockets' heartbreaking failure to launch","description":"Houston's stars thrived, Clint Capela emerged and all the pieces fell into place. But in the end, the Warriors and an untimely CP3 injury proved too much to overcome.","url":"http:\/\/www.espn.com\/nba\/story\/_\/id\/23634056\/the-houston-rockets-heartbreaking-failure-launch-nba","urlToImage":"http:\/\/a2.espncdn.com\/combiner\/i?img=%2Fphoto%2F2018%2F0528%2Fr377007_1296x729_16%2D9.jpg","publishedAt":"2018-05-29T04:44:35+00:00"},{"source":{"id":"google-news","name":"Google News"},"author":"Vivian Salama","title":"White House Halts New North Korea Sanctions in Mad Dash to Save Summit","description":"The U.S. decided to defer launching a major new sanctions push against North Korea, part of a flurry of weekend moves by both sides aimed at reviving a summit between President Trump and North Korea’s Kim Jong Un.","url":"https:\/\/www.wsj.com\/articles\/nations-race-to-save-korea-summit-1527547115","urlToImage":"https:\/\/images.wsj.net\/im-12257\/social","publishedAt":"2018-05-29T03:44:58+00:00"},{"source":{"id":"google-news","name":"Google News"},"author":"https:\/\/www.nytimes.com\/by\/matt-stevens","title":"TV Journalists Covering Storm Are Killed When Tree Crushes S.U.V. in North Carolina","description":"The news anchor and photojournalist for WYFF News 4 in Greenville, S.C., had been reporting on the effects of Subtropical Storm Alberto.","url":"https:\/\/www.nytimes.com\/2018\/05\/28\/us\/tv-news-crew-killed-falling-tree.html","urlToImage":"https:\/\/static01.nyt.com\/images\/2018\/05\/29\/us\/29WYFF\/29WYFF-facebookJumbo.jpg","publishedAt":"2018-05-29T03:13:51+00:00"},{"source":{"id":"google-news","name":"Google News"},"author":"Erik Ortiz, Tim Stelloh, Associated Press, Mary Murray, Matthew Vann","title":"Two journalists killed as Alberto makes landfall on Florida Panhandle","description":"Two journalists for NBC affiliate WYFF of Greenville, South Carolina, were killed when a tree fell on their car in North Carolina after Alberto made landfall.","url":"https:\/\/www.nbcnews.com\/news\/us-news\/storm-alberto-nearing-landfall-along-florida-panhandle-threatens-heavy-rains-n878021","urlToImage":"https:\/\/media3.s-nbcnews.com\/j\/newscms\/2018_22\/2446921\/180528-storm-alberto-florida-1059a-rs_356711a28e00435f2979771b572648ba.1200;630;7;70;5.JPG","publishedAt":"2018-05-29T02:32:29+00:00"},{"source":{"id":"google-news","name":"Google News"},"author":"Laurel Wamsley","title":"On Memorial Day, Trump Honors Fallen Soldiers; Draws Criticism Over Tweet","description":"\"They fought and bled and died so that America would forever remain safe and strong and free,\" Trump said at Arlington cemetery. Earlier, he drew criticism online for praise some found self-serving.","url":"https:\/\/www.npr.org\/sections\/thetwo-way\/2018\/05\/28\/614993465\/on-memorial-day-trump-honors-fal
05-29 12:59:15.395 9368-9528/com.example.pritom14.saveeverything W/System.err:     at org.json.JSON.typeMismatch(JSON.java:111)
05-29 12:59:15.398 9368-9528/com.example.pritom14.saveeverything W/System.err:     at org.json.JSONArray.<init>(JSONArray.java:96)
05-29 12:59:15.399 9368-9528/com.example.pritom14.saveeverything W/System.err:     at org.json.JSONArray.<init>(JSONArray.java:108)
        at com.example.pritom14.saveeverything.MainActivity.parseResult(MainActivity.java:109)
        at com.example.pritom14.saveeverything.MainActivity.access[=15=]0(MainActivity.java:28)
05-29 12:59:15.400 9368-9528/com.example.pritom14.saveeverything W/System.err:     at com.example.pritom14.saveeverything.MainActivity$DownloadTask.doInBackground(MainActivity.java:78)
        at com.example.pritom14.saveeverything.MainActivity$DownloadTask.doInBackground(MainActivity.java:49)
        at android.os.AsyncTask.call(AsyncTask.java:295)
05-29 12:59:15.401 9368-9528/com.example.pritom14.saveeverything W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:234)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
        at java.lang.Thread.run(Thread.java:818)
05-29 12:59:15.401 9368-9528/com.example.pritom14.saveeverything D/ResultForParsing :: null
05-29 14:54:04.099 16044-16149/com.example.pritom14.saveeverything D/ResponseForParsing :: {"status":"ok","totalResults":10,"articles":[{"source":{"id":"google-news","name":"Google News"},"author".....

谁能帮我解决这个问题?

谢谢

如果你检查你的根 JSON object,它包含作者、标题和文章数组中的描述,所以首先需要在 [=13= 中保存 "article" 数组]数组,然后使用这个数组获取作者、标题和描述字段

试试这个它肯定会起作用,因为你在结果参数中得到 json 对象。

private void parseResult(String result) {

        Log.e("result::>", result);
        try {
            JSONObject jsonObject = new JSONObject(result);
            if (jsonObject.getString("status").equalsIgnoreCase("ok")) {
                JSONArray jsonArray = jsonObject.getJSONArray("articles");
                modelList = new ArrayList<>();
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject post = jsonArray.optJSONObject(i);
                    Model item = new Model();
                    item.setAuthor(post.optString("author"));
                    item.setTitle(post.optString("title"));
                    item.setDescription(post.optString("description"));

                    modelList.add(item);
                    Log.d("AuthorForJSON : ", post.optString("author"));
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

希望对您有所帮助。

你需要做这样的事情。首先在你的 doInBackground method return 一个字符串而不是 integer

@Override
    protected String doInBackground(String... params) {
        String result = null;
        try {

           HttpsURLConnection urlConnection;

        try {
            URL url=new URL(strings[0]);
            urlConnection=(HttpsURLConnection)url.openConnection();
            int statusCode=urlConnection.getResponseCode();

            if (statusCode==200){
                BufferedReader br=new BufferedReader(
                        new InputStreamReader(urlConnection.getInputStream()));
                StringBuilder response=new StringBuilder();
                String line;
                while ((line=br.readLine()) !=null) {
                    response.append(line);
                }
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        } catch (final Exception e) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(getApplicationContext(), Common.EXCEPTION_ERROR_MSG, Toast.LENGTH_LONG).show();
                }
            });
        }
        return result;
    }

然后在你的 OnPostExecute()

 @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        JSONObject mJsonResponse;
        try {
            // Dismiss the progress dialog
            if (progressDialog != null) {
                progressDialog.dismiss();
            }

          parseResult(result);
    }catch(Exception ex){
 }
}

和您的 parseResult 方法相同:

 private void parseResult(String result){
    try {
        JSONArray posts=new JSONArray(result);
        modelList=new ArrayList<>();

        for (int i=0;i<posts.length();i++){
            JSONObject post=posts.optJSONObject(i);
            Model item=new Model();
            item.setAuthor(post.optString("author"));
            item.setTitle(post.optString("title"));
            item.setDescription(post.optString("description"));

            modelList.add(item);
            Log.d("AuthorForJSON : ",post.optString("author"));
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

我使用 Volley 解决了问题,它是一个 HTTP 库,使 Android 应用程序的网络更容易,最重要的是,速度更快。

首先,在app/build.gradle文件中:

implementation 'com.android.volley:volley:1.1.0' 

其次,我修改了我的MainActivity.java文件:

public class MainActivity extends AppCompatActivity {

private static final String TAG="MainActivity";
private List<Model> modelList;
private RecyclerView recyclerView;
private CustomAdapter customAdapter;
private RequestQueue requestQueue;

String url="https://newsapi.org/v2/top-headlines?sources=google-news&apiKey=76351c3c06504e12a8c61428162dcf87";

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

    recyclerView=(RecyclerView)findViewById(R.id.list);
    recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
    modelList=new ArrayList<>();
    requestQueue= Volley.newRequestQueue(this);

    parseJSON();
}

private void parseJSON(){
    JsonObjectRequest request=new JsonObjectRequest(Request.Method.GET, url, null,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    try {
                        JSONArray jsonArray = response.getJSONArray("articles");

                        for (int i = 0; i < jsonArray.length(); i++) {
                            JSONObject article = jsonArray.getJSONObject(i);
                            String news_author = article.getString("author");
                            String news_title = article.getString("title");
                            String news_descrip = article.getString("description");

                            modelList.add(new Model(news_author, news_title, news_descrip));
                        }

                        customAdapter = new CustomAdapter(MainActivity.this, modelList);
                        recyclerView.setAdapter(customAdapter);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            error.printStackTrace();
        }
    });

    requestQueue.add(request);
}
}

就是这样!!