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

时间:2018-05-29 07:25:48

标签: java android json android-recyclerview jsonparser

我正在尝试解析JSON中的https://newsapi.org数据,并将其显示在应用程序的recyclerview上。以下是JSON数据的示例opf:

 {
"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语句来显示连接是否正常,它返回1表示连接成功建立。

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$000(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$2.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$1.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".....

有人可以帮助我吗?

谢谢

4 个答案:

答案 0 :(得分:1)

试试这个,它会有效地工作,因为你在结果参数中得到了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();
        }
    }

希望它有所帮助。

答案 1 :(得分:1)

你需要做这样的事情。首先在doInBackground method中返回一个字符串,而不是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();
    }
}

答案 2 :(得分:0)

如果你检查你的根JSON对象,它包含articles数组中的作者,标题和描述,所以首先需要在JSONArray中保存“article”数组,然后使用这个数组来获取作者,标题和描述字段

答案 3 :(得分:0)

我使用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);
}
}

就是这样!!