android - android studio中空json的错误处理
问题描述
我正在尝试构建一个简单的新闻应用程序,从互联网上获取新闻标题,但我在这样做时遇到了一些问题。在我的应用程序中,如果我的 json 没有被解析,我只会得到一个空的回收站视图。在这种情况下,我想再次解析 json,有人可以帮我这样做吗
这是我的主要活动:
public class MainActivity extends AppCompatActivity {
private MainActivityViewModel mainActivityViewModel;
private RecyclerView recyclerView;
private RecyclerViewAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.news_view);
mainActivityViewModel = ViewModelProviders.of(this).get(MainActivityViewModel.class);
mainActivityViewModel.init();
mainActivityViewModel.getNews().observe(this, new Observer<List<NewsData>>() {
@Override
public void onChanged(List<NewsData> newsData) {
adapter.notifyDataSetChanged();
}
});
init();
}
private void init(){
Log.d("","=========================intializing Recycler view======================");
System.out.println("executing init()");
adapter = new RecyclerViewAdapter(mainActivityViewModel.mutableLiveData.getValue(), this);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(adapter);
}
}
这是 NewsRepository.java
public class NewsRepository {
MutableLiveData<List<NewsData>> liveNews = new MutableLiveData<>();
private static NewsRepository instance;
public static NewsRepository getInstance(){
if(instance != null)
return instance;
instance = new NewsRepository();
return instance;
}
private static final String LOG_TAG = "NewsRepository";
private static final String newsAPIurl = "https://newsapi.org/v2/top-headlines?sources=google-news-in&apiKey";
List<NewsData> newsDatalist = new ArrayList<>();
public void getLiveNews(){
new FetchJSONAsyncTask().execute();
}
public class FetchJSONAsyncTask extends AsyncTask<Void,Void,Void>{
@Override
protected Void doInBackground(Void... voids) {
Log.d("Backgroumd thread" , "Fetching json");
URL url = createUrl();
String jsonRespone = "";
try {
jsonRespone = makeHttpRequest(url);
}
catch (IOException e) {
Log.d("Background" , "Could not Load url");
}
extractNewsfromJSON(jsonRespone);
return null;
}
}
private URL createUrl() {
URL url = null;
try {
url = new URL(NewsRepository.newsAPIurl);
} catch (MalformedURLException exception) {
Log.e(LOG_TAG, "Error with creating URL", exception);
return null;
}
return url;
}
private String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(10000);
urlConnection.setConnectTimeout(15000);
urlConnection.connect();
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} catch (IOException e) {
Log.e(LOG_TAG,"there was an error in makeHTTPRequest" , e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
}
return jsonResponse;
}
private String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
private void extractNewsfromJSON(String newsJSON){
try{
JSONObject jsonObject = new JSONObject(newsJSON);
String a = jsonObject.getString("status");
System.out.println("=================================================");
System.out.println(a);
JSONArray newsArray = jsonObject.getJSONArray("articles");
if(newsArray.length() > 0){
for(int i =0 ;i< newsArray.length();i++){
JSONObject article = newsArray.getJSONObject(i);
String title = article.getString("title");
String desc = article.getString("description");
String urltoimg = article.getString("urlToImage");
String readmore = article.getString("url");
NewsData obj = new NewsData(title , desc, readmore , urltoimg);
newsDatalist.add(obj);
}
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Problem parsing the JSON results", e);
}
}
}
这是 MainActivityViewModel
public class MainActivityViewModel extends ViewModel {
private NewsRepository instance;
MutableLiveData<List<NewsData>> mutableLiveData;
public void init(){
if(instance != null)
return;
instance = NewsRepository.getInstance();
instance.getLiveNews();
mutableLiveData = instance.liveNews;
}
public LiveData<List<NewsData>> getNews(){
return mutableLiveData;
}
public void refreshNews(){
instance.getLiveNews();
}
}
解决方案
你的代码问题在于这个函数:
public MutableLiveData<List<NewsData>> getLiveNews(){
new FetchJSONAsyncTask().execute();
MutableLiveData<List<NewsData>> liveNews = new MutableLiveData<>();
System.out.println("==========================================");
liveNews.setValue(newsData);
return liveNews;
}
FetchJSONAsyncTask 是一个异步任务,您在从 API 获取数据之前返回 liveNews。它是空白的,因此您得到的是空的 RecyclerView。
这是您可以做的,创建 liveNews 一个类变量,而不是每次都创建一个新对象。
public class NewsRepository {
public MutableLiveData<List<NewsData>> liveNews = new MutableLiveData<>();
//rest of the code
更新您的 ViewModel 以直接从此变量中获取值:
public class MainActivityViewModel extends ViewModel {
private NewsRepository instance;
LiveData<List<NewsData>> LiveData;
public void init(){
if(instance != null)
return;
instance = NewsRepository.getInstance();
LiveData = instance.liveNews;
instance.getLiveNews() // call to fetch JSON first time
}
public LiveData<List<NewsData>> getNews(){
return LiveData;
}
//call this function from your activity to refresh the data
public void refreshNews(){
instance.getLiveNews();
}
}
现在您将 getLiveNews 方法更新为仅调用 FetchJSONAsyncTask。
public void getLiveNews(){
new FetchJSONAsyncTask().execute();
}
现在在 extractNewsfromJSON 方法中设置 liveNews 的值:
private void extractNewsfromJSON(String newsJSON){
try{
//rest of the code
liveNews.postValue(newsData);
}
} catch (JSONException e) {
System.out.println(newsJSON);
Log.e(LOG_TAG, "Problem parsing the JSON results", e);
}
}
推荐阅读
- php - json对象原始数据字段到php数组中
- python - Keras 时间序列交叉验证
- javascript - 结合来自同一响应的两个对象数组 - JS
- swift - 如何在 Swift 中使用 WK WebView 上传文件(.pdf)?
- php - 本地 PHP 和 React TSX 应用程序的 CORS 策略错误
- node.js - 如何在使用 pg-query-stream 和 pg-promise 进行流式传输时运行更新?
- linux - 在unix中按数字打印选定的行
- python - 在数据框的列上应用地图功能
- machine-learning - 我应该使用适合训练数据集的 MinMaxScaler 来转换测试数据集,还是使用单独的 MinMaxScaler 来拟合和转换测试数据集?
- java - 我想知道java 8中的`CurrentJDK/Classes`在哪里