Android JSON 解析输出问题
Android JSON parsing output issue
这是我人生中第一次使用 AsyncTaskLoader。我正在努力获取 RecyclerView 上的输出。
我检查了日志,似乎正确地解析了 JSON,但我不知道有什么问题不提供输出而是显示我有条件设置的 No news found
文本。
我附上 MainActivity
代码,完整的项目回购是 here
主要活动
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<News>> {
public static final String LOG_TAG = MainActivity.class.getSimpleName();
private static final int NEWS_LOADER_ID = 1;
private static String NEWS_REQUEST_URL = "https://content.guardianapis.com/search?tag=world/india&format=json&show-tags=contributor&show-fields=starRating,headline,trailText,thumbnail,publication&api-key=test";
private ArrayList<News> mNews;
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private RecyclerView.Adapter mAdapter;
private TextView emptyView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.news_list);
emptyView = findViewById(R.id.empty_list);
// if (mNews.isEmpty()) {
// mRecyclerView.setVisibility(View.GONE);
// emptyView.setVisibility(View.VISIBLE);
// } else {
// mRecyclerView.setVisibility(View.VISIBLE);
// emptyView.setVisibility(View.GONE);
// }
mNews = new ArrayList<>();
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mAdapter = new NewsAdapter(mNews, this);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
// connection
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
LoaderManager loaderManager = getSupportLoaderManager();
loaderManager.initLoader(NEWS_LOADER_ID, null, this);
} else {
View loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
emptyView.setText(R.string.no_internet_connection);
}
}
@NonNull
@Override
public Loader<List<News>> onCreateLoader(int id, @Nullable Bundle args) {
return new NewsLoader(this, NEWS_REQUEST_URL);
}
@Override
public void onLoadFinished(@NonNull Loader<List<News>> loader, List<News> data) {
View loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
emptyView.setText(R.string.no_news_found);
mNews.clear(); //@TODO: cross check the clearing method
if (data != null && !data.isEmpty()) {
mNews.addAll(data);
Log.d(LOG_TAG, "All News " + mNews.toString()); // I am getting output here. See the log in quote below
}
}
@Override
public void onLoaderReset(@NonNull Loader<List<News>> loader) {
mNews.clear();
}
}
Log.d 用于 onLoadFinished() 方法中的所有新闻
2019-01-27 13:57:44.010 15097-15097/com.codepaints.theindiannews D/MainActivity: All News [News{mSectionName='World news', mWebPublicationDate='2019-01-25T10:39:45Z', mWebUrl='https://www.theguardian.com/world/2019/jan/25/ill-destroy-you-all-indian-historical-epic-star-critics-manikarnika', mHeadline='Bollywood epic Manikarnika tells tale of India's anti-British queen', mThumbnail='https://media.guim.co.uk/40162001e73356a1c8c9608aac0db222e5cfc773/375_0_1797_1078/500.jpg', mWebTitle='Michael Safi', mPillarName='News'}, News{mSectionName='Film', mWebPublicationDate='2019-01-25T08:00:29Z', mWebUrl='https://www.theguardian.com/film/2019/jan/25/love-sonia-review-sex-trafficking-drama-tabrez-noorani', mHeadline='Love Sonia review – flawed but powerful sex-trafficking drama', mThumbnail='https://media.guim.co.uk/037b8adb793f5542e8735f3e9411ec1ea33e8d9b/0_32_960_576/500.jpg', mWebTitle='Cath Clarke', mPillarName='Arts'}, News{mSectionName='World news', mWebPublicationDate='2019-01-24T12:10:28Z', mWebUrl='https://www.theguardian.com/world/2019/jan/24/indian-traders-film-fans-steal-milk-pour-posters-tamil-nadu', mHeadline='Indian traders say film fans are stealing milk to pour over posters', mThumbnail='https://media.guim.co.uk/5f3d4a6d3bf7b3f64f0b1042315f2967c2aff08f/0_40_4000_2400/500.jpg', mWebTitle='Michael Safi', mPillarName='News'}, News{mSectionName='World news', mWebPublicationDate='2019-01-23T14:37:54Z', mWebUrl='https://www.theguardian.com/world/2019/jan/23/priyanka-gandhi-enters-politics-months-before-india-general-election', mHeadline='Priyanka Gandhi enters politics months before India general election', mThumbnail='https://media.guim.co.uk/6904e125bedbecaad50f5c4e31397f7a14a97c3f/0_228_5000_3001/500.jpg', mWebTitle='Michael Safi', mPillarName='News'}, News{mSectionName='World news', mWebPublicationDate='2019-01-23T08:39:17Z', mWebUrl='https://www.theguardian.com/world/2019/jan/23/woman-indian-temple-family-sabarimala-kerala', mHeadline='Woman who defied Indian temple ban 'shunned' by family', mThumbnail='https://media.guim.co.uk/bfe16ae84d46259b70da00e240b4d867ef4cc178/0_0_1798_1079/500.jpg', mWebTitle='Michael Safi', mPillarName='News'}, News{mSectionName='Global development', mWebPublicationDate='2019-01-23T06:00:12Z', mWebUrl='https://www.theguardian.com/global-development/2019/jan/23/tired-dark-fields-jeering-men-bride-led-toilet-revolution', mHeadline='Tired of dark fields and jeering men: the bride who led a 'toilet revolution'', mThumbnail='https://media.guim.co.uk/70ea2a81cf5d9d499aea14e28332523697ddd8d0/0_619_4128_2477/500.jpg', mWebTitle='Amrit Dhillon', mPillarName='News'}, News{mSectionName='Australia news', mWebPublicationDate='2019-01-22T04:38:22Z', mWebUrl='https://www.theguardian.com/australia-news/2019/jan/22/indian-woman-says-australian-boss-exploited-her-after-her-husband-got-cancer', mHeadline='Indian woman says Australian boss exploited her after her husband got cancer', mThumbnail='https://media.guim.co.uk/109ea39e65c673f94f17df9ced13bf5254db9f9c/255_781_4138_2483/500.jpg', mWebTitle='Ben Smee', mPillarName='News'}, News{mSectionName='World news', mWebPublicationDate='2019-01-20T07:00:12Z', mWebUrl='https://www.theguardian.com/world/2019/jan/20/magic-big-screen-defying-separatists-cinema-kashmir', mHeadline='Magic of big screen returns to Kashmir after Islamist ban', mThumbnail='https://media.guim.co.uk/a28d591b4bdebe31baabcdd2b4e5abde7084b5c5/0_77_3000_1800/500.jpg', mWebTitle='Amrit Dhillon', mPillarName='News'}, News{mSectionName='Art and design', mWebPublicationDate='2019-01-18T15:05:47Z', mWebUrl='https://www.theguardian.com/artanddesign/2019/jan/18/hardeep-pandhal-artist-paranoid-picnic-colonial-identity', mHeadline='Hardeep Pandhal: the rapping artist who works with his mum', mThumbnail='https://media.guim.co.uk/2982bba8e5ac2f4080ef8a473815882420d46163/2096_1081_2876_1726/500.jpg', mWebTitle='', mPillarName='Arts'}, News{mSectionName='World news', mWebPublicationDate='2019-01-18T11:09:23Z', mWebUrl='https://www.theguardian.com/world/2019/jan/18/kumbh-mela-worlds-largest-festival-lost-and-found', mHeadline=''I have lost my w... I think here is a string limit.
结果屏幕
这是我得到的而不是结果。
您的代码看起来一切正常,但我看不到您在何处调用 notifyDataSetChanged();
,因为您已经设置了适配器并且当时没有数据。因此,一旦数据加载到 if (data != null && !data.isEmpty())
中,调用 notifyDataSetChanged();
;
notifyDatasetChanged()
告诉ListView / RecyclerView
数据已经修改;并显示新数据,因此必须重绘 ListView / RecyclerView
。
@Override
public void onLoadFinished(@NonNull Loader<List<News>> loader, List<News> data) {
View loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
emptyView.setText(R.string.no_news_found);
mNews.clear(); //@TODO: cross check the clearing method
if (data != null && !data.isEmpty()) {
mNews.addAll(data);
mAdapter.notifydatasetchanged();//not updated
Log.d(LOG_TAG, "All News " + mNews.toString()); // I am getting output here. See the log in quote below
}
}
@Override
public void onLoadFinished(@NonNull Loader<List<News>> loader, List<News> data) {
View loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
emptyView.setText(R.string.no_news_found);
mNews.clear(); //@TODO: cross check the clearing method
if (data != null && !data.isEmpty()) {
mNews.addAll(data);
mAdapter.notifydatasetchanged();//not updated
Log.d(LOG_TAG, "All News " + mNews.toString()); // I am getting output here. See the log in quote below
}
}
这是我人生中第一次使用 AsyncTaskLoader。我正在努力获取 RecyclerView 上的输出。
我检查了日志,似乎正确地解析了 JSON,但我不知道有什么问题不提供输出而是显示我有条件设置的 No news found
文本。
我附上 MainActivity
代码,完整的项目回购是 here
主要活动
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<News>> {
public static final String LOG_TAG = MainActivity.class.getSimpleName();
private static final int NEWS_LOADER_ID = 1;
private static String NEWS_REQUEST_URL = "https://content.guardianapis.com/search?tag=world/india&format=json&show-tags=contributor&show-fields=starRating,headline,trailText,thumbnail,publication&api-key=test";
private ArrayList<News> mNews;
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private RecyclerView.Adapter mAdapter;
private TextView emptyView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.news_list);
emptyView = findViewById(R.id.empty_list);
// if (mNews.isEmpty()) {
// mRecyclerView.setVisibility(View.GONE);
// emptyView.setVisibility(View.VISIBLE);
// } else {
// mRecyclerView.setVisibility(View.VISIBLE);
// emptyView.setVisibility(View.GONE);
// }
mNews = new ArrayList<>();
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mAdapter = new NewsAdapter(mNews, this);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
// connection
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
LoaderManager loaderManager = getSupportLoaderManager();
loaderManager.initLoader(NEWS_LOADER_ID, null, this);
} else {
View loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
emptyView.setText(R.string.no_internet_connection);
}
}
@NonNull
@Override
public Loader<List<News>> onCreateLoader(int id, @Nullable Bundle args) {
return new NewsLoader(this, NEWS_REQUEST_URL);
}
@Override
public void onLoadFinished(@NonNull Loader<List<News>> loader, List<News> data) {
View loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
emptyView.setText(R.string.no_news_found);
mNews.clear(); //@TODO: cross check the clearing method
if (data != null && !data.isEmpty()) {
mNews.addAll(data);
Log.d(LOG_TAG, "All News " + mNews.toString()); // I am getting output here. See the log in quote below
}
}
@Override
public void onLoaderReset(@NonNull Loader<List<News>> loader) {
mNews.clear();
}
}
Log.d 用于 onLoadFinished() 方法中的所有新闻
2019-01-27 13:57:44.010 15097-15097/com.codepaints.theindiannews D/MainActivity: All News [News{mSectionName='World news', mWebPublicationDate='2019-01-25T10:39:45Z', mWebUrl='https://www.theguardian.com/world/2019/jan/25/ill-destroy-you-all-indian-historical-epic-star-critics-manikarnika', mHeadline='Bollywood epic Manikarnika tells tale of India's anti-British queen', mThumbnail='https://media.guim.co.uk/40162001e73356a1c8c9608aac0db222e5cfc773/375_0_1797_1078/500.jpg', mWebTitle='Michael Safi', mPillarName='News'}, News{mSectionName='Film', mWebPublicationDate='2019-01-25T08:00:29Z', mWebUrl='https://www.theguardian.com/film/2019/jan/25/love-sonia-review-sex-trafficking-drama-tabrez-noorani', mHeadline='Love Sonia review – flawed but powerful sex-trafficking drama', mThumbnail='https://media.guim.co.uk/037b8adb793f5542e8735f3e9411ec1ea33e8d9b/0_32_960_576/500.jpg', mWebTitle='Cath Clarke', mPillarName='Arts'}, News{mSectionName='World news', mWebPublicationDate='2019-01-24T12:10:28Z', mWebUrl='https://www.theguardian.com/world/2019/jan/24/indian-traders-film-fans-steal-milk-pour-posters-tamil-nadu', mHeadline='Indian traders say film fans are stealing milk to pour over posters', mThumbnail='https://media.guim.co.uk/5f3d4a6d3bf7b3f64f0b1042315f2967c2aff08f/0_40_4000_2400/500.jpg', mWebTitle='Michael Safi', mPillarName='News'}, News{mSectionName='World news', mWebPublicationDate='2019-01-23T14:37:54Z', mWebUrl='https://www.theguardian.com/world/2019/jan/23/priyanka-gandhi-enters-politics-months-before-india-general-election', mHeadline='Priyanka Gandhi enters politics months before India general election', mThumbnail='https://media.guim.co.uk/6904e125bedbecaad50f5c4e31397f7a14a97c3f/0_228_5000_3001/500.jpg', mWebTitle='Michael Safi', mPillarName='News'}, News{mSectionName='World news', mWebPublicationDate='2019-01-23T08:39:17Z', mWebUrl='https://www.theguardian.com/world/2019/jan/23/woman-indian-temple-family-sabarimala-kerala', mHeadline='Woman who defied Indian temple ban 'shunned' by family', mThumbnail='https://media.guim.co.uk/bfe16ae84d46259b70da00e240b4d867ef4cc178/0_0_1798_1079/500.jpg', mWebTitle='Michael Safi', mPillarName='News'}, News{mSectionName='Global development', mWebPublicationDate='2019-01-23T06:00:12Z', mWebUrl='https://www.theguardian.com/global-development/2019/jan/23/tired-dark-fields-jeering-men-bride-led-toilet-revolution', mHeadline='Tired of dark fields and jeering men: the bride who led a 'toilet revolution'', mThumbnail='https://media.guim.co.uk/70ea2a81cf5d9d499aea14e28332523697ddd8d0/0_619_4128_2477/500.jpg', mWebTitle='Amrit Dhillon', mPillarName='News'}, News{mSectionName='Australia news', mWebPublicationDate='2019-01-22T04:38:22Z', mWebUrl='https://www.theguardian.com/australia-news/2019/jan/22/indian-woman-says-australian-boss-exploited-her-after-her-husband-got-cancer', mHeadline='Indian woman says Australian boss exploited her after her husband got cancer', mThumbnail='https://media.guim.co.uk/109ea39e65c673f94f17df9ced13bf5254db9f9c/255_781_4138_2483/500.jpg', mWebTitle='Ben Smee', mPillarName='News'}, News{mSectionName='World news', mWebPublicationDate='2019-01-20T07:00:12Z', mWebUrl='https://www.theguardian.com/world/2019/jan/20/magic-big-screen-defying-separatists-cinema-kashmir', mHeadline='Magic of big screen returns to Kashmir after Islamist ban', mThumbnail='https://media.guim.co.uk/a28d591b4bdebe31baabcdd2b4e5abde7084b5c5/0_77_3000_1800/500.jpg', mWebTitle='Amrit Dhillon', mPillarName='News'}, News{mSectionName='Art and design', mWebPublicationDate='2019-01-18T15:05:47Z', mWebUrl='https://www.theguardian.com/artanddesign/2019/jan/18/hardeep-pandhal-artist-paranoid-picnic-colonial-identity', mHeadline='Hardeep Pandhal: the rapping artist who works with his mum', mThumbnail='https://media.guim.co.uk/2982bba8e5ac2f4080ef8a473815882420d46163/2096_1081_2876_1726/500.jpg', mWebTitle='', mPillarName='Arts'}, News{mSectionName='World news', mWebPublicationDate='2019-01-18T11:09:23Z', mWebUrl='https://www.theguardian.com/world/2019/jan/18/kumbh-mela-worlds-largest-festival-lost-and-found', mHeadline=''I have lost my w... I think here is a string limit.
结果屏幕
这是我得到的而不是结果。
您的代码看起来一切正常,但我看不到您在何处调用 notifyDataSetChanged();
,因为您已经设置了适配器并且当时没有数据。因此,一旦数据加载到 if (data != null && !data.isEmpty())
中,调用 notifyDataSetChanged();
;
notifyDatasetChanged()
告诉ListView / RecyclerView
数据已经修改;并显示新数据,因此必须重绘 ListView / RecyclerView
。
@Override
public void onLoadFinished(@NonNull Loader<List<News>> loader, List<News> data) {
View loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
emptyView.setText(R.string.no_news_found);
mNews.clear(); //@TODO: cross check the clearing method
if (data != null && !data.isEmpty()) {
mNews.addAll(data);
mAdapter.notifydatasetchanged();//not updated
Log.d(LOG_TAG, "All News " + mNews.toString()); // I am getting output here. See the log in quote below
}
}
@Override
public void onLoadFinished(@NonNull Loader<List<News>> loader, List<News> data) {
View loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
emptyView.setText(R.string.no_news_found);
mNews.clear(); //@TODO: cross check the clearing method
if (data != null && !data.isEmpty()) {
mNews.addAll(data);
mAdapter.notifydatasetchanged();//not updated
Log.d(LOG_TAG, "All News " + mNews.toString()); // I am getting output here. See the log in quote below
}
}