为什么不显示所有数据?

时间:2019-05-14 06:15:36

标签: android android-asynctask httpresponse

我正在创建一个显示最新新闻的应用程序,该应用程序从 https://newsapi.org/s/india-health-news-api 但它不会获取所有数据。有时它只显示全部,但有时它只显示2或3个新闻。另外,我没有看到任何日志错误消息。问题是什么?

HealthNews.java

public class HealthNews extends AppCompatActivity {
private ArrayList urlList;
private NewsAdapter mNewsAdapter;

private static final String REQUEST_URL ="https://newsapi.org/v2/top-headlines?country=in&category=health&apiKey=3f7d99cdbb004766892bd239a4c099be";

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

    Intent intent = getIntent();
    HealthNews.NewsAsyncTask task = new HealthNews.NewsAsyncTask();
    task.execute(REQUEST_URL);

    urlList = QueryUtils.m;

    ListView listView = (ListView)findViewById(R.id.listViewHealthNews);

    mNewsAdapter = new NewsAdapter(this, new ArrayList<News>());
    listView.setAdapter(mNewsAdapter);

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            //Toast.makeText(getApplicationContext(), ""+ a.get(position), Toast.LENGTH_SHORT).show();

            Object url = urlList.get(position);
            Uri uri = (Uri) Uri.parse((String) url); // missing 'http://' will cause crashed
            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            startActivity(intent);

        }
    });
}

private class NewsAsyncTask extends AsyncTask<String, Void, ArrayList<News>> {
    ProgressDialog p;

    @Override
    protected ArrayList<News> doInBackground(String... urls) {
        if (urls.length < 1 || urls[0] == null) {
            return null;
        }

        ArrayList<News> result = QueryUtils.fetchEarthquakeData(urls[0]);
        return result;
        //return null;
    }

    @Override
    protected void onPostExecute(ArrayList<News> data) {
        mNewsAdapter.clear();

        if (data != null && !data.isEmpty()) {
            p.hide();
            mNewsAdapter.addAll(data);
        }
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        p = new ProgressDialog(HealthNews.this);
        p.setMessage("Latest News...");
        p.setIndeterminate(false);
        p.show();
    }

}
}

QueryUtils.java

private static final String LOG_TAG = "";

private QueryUtils(){
}

private static URL createUrl(String stringUrl) {
    URL url = null;
    try {
        url = new URL(stringUrl);
    } catch (MalformedURLException e) {
        Log.e(LOG_TAG, "Problem building the URL ", e);
    }
    return url;
}

private static String makeHttpRequest(URL url) throws IOException {
    String jsonResponse = "";

    // If the URL is null, then return early.
    if (url == null) {
        return jsonResponse;
    }

    HttpURLConnection urlConnection = null;
    InputStream inputStream = null;
    try {
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setReadTimeout(30000 /* milliseconds */);
        urlConnection.setConnectTimeout(60000 /* milliseconds */);
        urlConnection.setRequestMethod("GET");
        urlConnection.connect();

        if (urlConnection.getResponseCode() == 200) {
            inputStream = urlConnection.getInputStream();
            jsonResponse = readFromStream(inputStream);
        } else {
            Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
        }
    } catch (IOException e) {
        Log.e(LOG_TAG, "Problem retrieving the earthquake JSON results.", e);
    } finally {
        if (urlConnection != null) {
            urlConnection.disconnect();
        }
        if (inputStream != null) {
            inputStream.close();
        }
    }
    return jsonResponse;
}

private static String readFromStream(InputStream inputStream) throws IOException {
    StringBuilder output = new StringBuilder();
    if (inputStream != null) {
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
        BufferedReader reader = new BufferedReader(inputStreamReader);
        String line = reader.readLine();
        while (line != null) {
            output.append(line);
            line = reader.readLine();
        }
    }
    return output.toString();
}

static ArrayList<String> m = new ArrayList<String>();

public static ArrayList<News> extractNews(String SAMPLE_JSON){
    if (TextUtils.isEmpty(SAMPLE_JSON)) {
        return null;
    }

    ArrayList<News> news = new ArrayList<News>();
    try {

        JSONObject jsonObject1 = new JSONObject(SAMPLE_JSON);
        JSONArray baseJSONArray = jsonObject1.getJSONArray("articles");

        for (int i = 0; i < baseJSONArray.length(); i++) {
            JSONObject jsonObject = baseJSONArray.getJSONObject(i);
            JSONObject source = jsonObject.getJSONObject("source");

            String name = source.getString("name");
            String article = jsonObject.getString("title");
            String url1 = jsonObject.getString("url");
            String img = jsonObject.getString("urlToImage");
            URL url = new URL(img);
            Bitmap image = BitmapFactory.decodeStream(url.openConnection().getInputStream());

            News a = new News(image, article);
            news.add(a);
            m.add(url1);
        }
    } catch (JSONException j) {

    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return news;
}
public static ArrayList<News> fetchEarthquakeData(String requestUrl) {
    URL url = createUrl(requestUrl);

    String jsonResponse = null;
    try {
        jsonResponse = makeHttpRequest(url);
    } catch (IOException e) {
        Log.e(LOG_TAG, "Problem making the HTTP request.", e);
    }

    ArrayList<News> news = extractNews(jsonResponse);

    return news;
}

1 个答案:

答案 0 :(得分:1)

我仔细阅读了您的代码,发现了一些问题。

我在您的代码中发现的一些不良做法是:

  1. 您正在使用static指定符将网址添加到单独的列表中。代替此,您应该在News模型中直接添加url变量。您可以直接在New内检索整个ListView > setOnItemClickListener的模型。
  2. 您正在为所有图像创建Bitmap。它可能导致OOM Exception。您应该改用任何图片加载库。

我已解决所有问题并创建了工作代码。请在结束时进行所需的更改。

  

HealthNews.java

public class HealthNews extends AppCompatActivity {

    private Context context;
    private NewsAdapter mNewsAdapter;

    private ArrayList<News> listNews;

    private static final String REQUEST_URL = "https://newsapi.org/v2/top-headlines?country=in&category=health&apiKey=3f7d99cdbb004766892bd239a4c099be";

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

        context = this;

        ListView list_news = findViewById(R.id.list_news);

        listNews = new ArrayList<>();

        mNewsAdapter = new NewsAdapter(context, listNews);
        list_news.setAdapter(mNewsAdapter);

        list_news.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                try {
                    News selNews = (News) parent.getAdapter().getItem(position);
                    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(selNews.getUrl())));
                } catch (Exception e) {
                    // Missing 'http://' or 'https://' will cause crash
                    e.printStackTrace();
                }
            }
        });

        new NewsAsyncTask().execute(REQUEST_URL);
    }

    private class NewsAsyncTask extends AsyncTask<String, Void, ArrayList<News>> {

        private ProgressDialog p;

        @Override
        public void onPreExecute() {
            super.onPreExecute();
            p = new ProgressDialog(context);
            p.setMessage("Latest News...");
            p.setIndeterminate(false);
            p.show();
        }

        @Override
        public ArrayList<News> doInBackground(String... urls) {
            return QueryUtils.fetchEarthquakeData(urls[0]);
        }

        @Override
        public void onPostExecute(ArrayList<News> newsList) {
            super.onPostExecute(newsList);
            listNews.addAll(newsList);
            p.hide();
            mNewsAdapter.notifyDataSetChanged();
        }
    }
}
  

QueryUtils.java

public class QueryUtils {

    public static ArrayList<News> fetchEarthquakeData(String apiUrl) {

        ArrayList<News> listNews = new ArrayList<>();

        try {

            URL url = new URL(apiUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(30000);
            conn.setConnectTimeout(60000);
            conn.setRequestMethod("GET");
            conn.connect();

            int responseCode = conn.getResponseCode();

            InputStream iStream;

            if (responseCode == HttpURLConnection.HTTP_OK)
                iStream = conn.getInputStream();
            else
                iStream = conn.getErrorStream();

            BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

            StringBuilder response = new StringBuilder();

            String line;

            while ((line = br.readLine()) != null) {
                response.append(line);
            }

            String jsonResponse = response.toString();

            if (TextUtils.isEmpty(jsonResponse))
                return null;

            JSONObject jsonObject1 = new JSONObject(jsonResponse);
            JSONArray baseJSONArray = jsonObject1.getJSONArray("articles");

            for (int i = 0; i < baseJSONArray.length(); i++) {

                JSONObject jsonObject = baseJSONArray.getJSONObject(i);
                JSONObject source = jsonObject.getJSONObject("source");

                News news = new News();
                news.setArticle(jsonObject.optString("title"));
                news.setUrl(jsonObject.optString("url"));
                news.setUrlToImage(jsonObject.optString("urlToImage"));

                listNews.add(news);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return listNews;
    }
}
  

News.java(模型)

public class News {

    private String article;
    private String url;
    private String urlToImage;

    public News() {
        this.article = "";
        this.url = "";
        this.urlToImage = "";
    }

    public String getArticle() {
        return article;
    }

    public void setArticle(String article) {
        this.article = article;
    }

    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;
    }
}
  

NewsAdapter.java(根据您的代码更改项目布局)

public class NewsAdapter extends BaseAdapter {

    private Context context;
    private LayoutInflater mInflater;

    private List<News> listNews;

    public NewsAdapter(Context context, List<News> listNews) {

        this.context = context;
        this.listNews = listNews;

        mInflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return listNews.size();
    }

    @Override
    public News getItem(int position) {
        return listNews.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    private class ViewHolder {
        private ImageView item_img_news;
        private TextView item_txt_article;
    }

    @SuppressLint("InflateParams")
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        final ViewHolder holder;

        if (convertView == null) {

            convertView = mInflater.inflate(R.layout.item_news, null);

            holder = new ViewHolder();

            holder.item_img_news = convertView.findViewById(R.id.item_img_news);
            holder.item_txt_article = convertView.findViewById(R.id.item_txt_article);

            convertView.setTag(holder);

        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        final News news = getItem(position);

        holder.item_txt_article.setText(news.getArticle());

        Glide.with(context).load(news.getUrlToImage()).into(holder.item_img_news);

        return convertView;
    }
}
  

app> build.gradle

implementation 'com.github.bumptech.glide:glide:4.9.0'