在android studio中对空json的错误处理

问题描述 投票:0回答:1

我正试图建立一个简单的新闻应用程序,从互联网上获取新闻标题,但我面临着一些问题,在这样做.在我的应用程序,如果我的如果json是不解析,我只是得到一个空的回收器视图。在这种情况下,我想再次解析json,有人能帮助我做这个事情吗?

这是我的MainActivity。



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

}

android json api
1个回答
0
投票

你的代码的问题在于这个函数。

 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);
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.