我正在创建一个显示最新新闻的应用程序,该应用程序从 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;
}
答案 0 :(得分:1)
我仔细阅读了您的代码,发现了一些问题。
我在您的代码中发现的一些不良做法是:
static
指定符将网址添加到单独的列表中。代替此,您应该在News
模型中直接添加url变量。您可以直接在New
内检索整个ListView > setOnItemClickListener
的模型。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'