Ничего не отображается при разборе данных JSON - PullRequest
0 голосов
/ 29 мая 2018

Я пытаюсь проанализировать JSON данные из https://newsapi.org и отобразить их на 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 для отображения, если соединение в порядке, и оно возвращает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, title и description.

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 голосов
/ 29 мая 2018

Я решил проблему с помощью 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);
}
}

И это все !!

0 голосов
/ 29 мая 2018

Попробуйте, это определенно будет работать, потому что вы получаете объект 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();
        }
    }

Надеюсь, это поможет.

0 голосов
/ 29 мая 2018

вам нужно сделать что-то подобное.Сначала в вашем 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();
    }
}
0 голосов
/ 29 мая 2018

если вы проверяете свой корневой объект JSON, он содержит автора, заголовок и описание внутри массива статей, поэтому сначала нужно сохранить массив "article" в JSONArray, а затем использовать этот массив для извлечения поля автора, заголовка и описания

...