我正在尝试从不同的URL获取数据,然后在后台加载

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

我已经使用一个URL构建了我的应用程序,并且该应用程序可以正常运行。但是MainMainity.java中“ onCreateLoader”方法的无与伦比的返回存在一个问题。

我使用后台线程毫无问题地加载所有数据。 MainActivity.java中的onCreateLoader方法应返回Loader>,并且有一个类NewsLoader.java扩展了AsyncTaskLoader>。

我想在onCreateLoader方法中返回新的NewsLoader,但此方法存在无与伦比的返回错误,即使我之前在另一个类似的应用程序中都很难做到这一点。

MainActivity.java

package com.example.newsapp;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.content.Loader;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.app.LoaderManager.LoaderCallbacks;
import android.app.LoaderManager;
import android.content.Context;

import java.util.ArrayList;
import java.util.List;



public class MainActivity extends AppCompatActivity implements LoaderCallbacks<List<Event>> {

    private EventAdapter mAdapter;
    private static final int LOADER_ID = 1;
    private static final String REQUEST_URL_1 = "http://content.guardianapis.com/search?q=debates&api-key=test\n";
    private static final String REQUEST_URL_2 = "https://content.guardianapis.com/search?q=debate&tag=politics/politics&from-date=2014-01-01&api-key=test\n";

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

        ListView earthquakeListView = findViewById(R.id.list_of_news);
        mAdapter = new EventAdapter(this, new ArrayList<Event>());
        earthquakeListView.setAdapter(mAdapter);

        earthquakeListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                Event currentEvent = mAdapter.getItem(position);

                assert currentEvent != null;
                Uri eventUri = Uri.parse(currentEvent.getURL());

                Intent websiteIntent = new Intent(Intent.ACTION_VIEW, eventUri);
                startActivity(websiteIntent);
            }
        });

        getLoaderManager().initLoader(LOADER_ID, null, this);
    }

    @NonNull
    @Override
    public Loader<List<Event>> onCreateLoader(int id, Bundle args) {
        return new NewsLoader(MainActivity.this, REQUEST_URL_1, REQUEST_URL_2);
    }

    @Override
    public void onLoadFinished(Loader<List<Event>> loader, List<Event> news) {
        mAdapter.clear();

        if (news != null && !news.isEmpty()) {
            mAdapter.addAll(news);
        }
    }

    @Override
    public void onLoaderReset(Loader<List<Event>> loader) {
        mAdapter.clear();
    }
}

NewsLoader.java

package com.example.newsapp;

import android.content.Context;

import androidx.loader.content.AsyncTaskLoader;

import java.util.List;


public class NewsLoader extends AsyncTaskLoader<List<Event>> {

    private static final String LOG_TAG = NewsLoader.class.getName();
    private String mUrl1;
    private String mUrl2;

    public NewsLoader(Context context, String url1, String url2) {
        super(context);
        mUrl1 = url1;
        mUrl2 = url2;
    }

    @Override
    protected void onStartLoading() {
        forceLoad();
    }

    @Override
    public List<Event> loadInBackground() {
        if (mUrl1 == null && mUrl2 == null) { return null; }

        // Perform the network request, parse the response, and extract a list of earthquakes.
        List<Event> news = QueryUtils.fetchNewsData(mUrl1, mUrl2);
        return news;
    }
}

QueryUtils.java

package com.example.newsapp;

import android.text.TextUtils;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public class QueryUtils {
    private static final String LOCATION_SEPARATOR = "T";
    public static final String LOG_TAG = QueryUtils.class.getSimpleName();

    private QueryUtils() {
    }

    public static List<Event> fetchNewsData(String requestUrl1, String requestUrl2) {
        URL url1 = createUrl(requestUrl1);
        URL url2 = createUrl(requestUrl2);

        String jsonResponse1 = null;
        String jsonResponse2 = null;
        try {
            jsonResponse1 = makeHttpRequest(url1);
            jsonResponse2 = makeHttpRequest(url2);
        } catch (IOException e) {
            Log.e(LOG_TAG, "Problem making the HTTP request.", e);
        }

        List<Event> news = extractEvents(jsonResponse1, jsonResponse2);
        return news;
    }

    public static List<Event> extractEvents(String eventJSON1, String eventJSON2) {

        // verify that there's data in one link at list
        if (TextUtils.isEmpty(eventJSON1) && TextUtils.isEmpty(eventJSON2)) {
            return null;
        }

        List<Event> news = new ArrayList<>();
        try {

            //getting results array from first link
            JSONObject baseJsonResponse1 = new JSONObject(eventJSON1);
            JSONObject mainObject1 = baseJsonResponse1.getJSONObject("response");
            JSONArray eventArray1 = mainObject1.getJSONArray("results");
            //getting results array from second link
            JSONObject baseJsonResponse2 = new JSONObject(eventJSON2);
            JSONObject mainObject2 = baseJsonResponse2.getJSONObject("response");
            JSONArray eventArray2 = mainObject2.getJSONArray("results");

            // reading required data from array of first link
            for (int i = 0; i<eventArray1.length(); i++){
                JSONObject currentEvent = eventArray1.getJSONObject(i);

                //getting url
                String webUrl = currentEvent.getString("webUrl");
                //getting title
                String webTitle = currentEvent.getString("webTitle");
                //getting sectionName
                String sectionName = currentEvent.getString("sectionName");
                //getting webPublicationDate
                String webPublicationDate = currentEvent.getString("webPublicationDate");
                String date = "0000 - 00 - 00";
                String time = "00:00:00";
                if (webPublicationDate.contains(LOCATION_SEPARATOR)) {
                    String[] parts = webPublicationDate.split(LOCATION_SEPARATOR);
                    date = parts[0];
                    time = parts[1].substring(0, parts[1].length() - 1);
                }

                // Make Quake Of the Strings And Assigning it to earthquakes ArrayList<Quake>
                Event quake = new Event(sectionName, webTitle, date, time, webUrl);
                news.add(quake);
            }
            // reading required data from array of first link
            for (int i = 0; i<eventArray2.length(); i++){
                JSONObject currentEvent = eventArray2.getJSONObject(i);

                //getting url
                String webUrl = currentEvent.getString("webUrl");
                //getting title
                String webTitle = currentEvent.getString("webTitle");
                //getting sectionName
                String sectionName = currentEvent.getString("sectionName");
                //getting webPublicationDate
                String webPublicationDate = currentEvent.getString("webPublicationDate");
                String date = "0000 - 00 - 00";
                String time = "00:00:00";
                if (webPublicationDate.contains(LOCATION_SEPARATOR)) {
                    String[] parts = webPublicationDate.split(LOCATION_SEPARATOR);
                    date = parts[0];
                    time = parts[1].substring(0, parts[1].length() - 1);
                }

                // Make Quake Of the Strings And Assigning it to earthquakes ArrayList<Quake>
                Event quake = new Event(sectionName, webTitle, date, time, webUrl);
                news.add(quake);
            }

        } catch (JSONException e) {
            Log.e("QueryUtils", "Problem parsing the news JSON results", e);
        }
        // Return the list of earthquakes
        return news;
    }

    private static URL createUrl(String requestUrl) {
        URL url = null;
        try {
            url = new URL(requestUrl);
        } catch (MalformedURLException exception) {
            Log.e(LOG_TAG, "Error with creating URL", exception);
            return null;
        }
        return url;
    }

    private static String makeHttpRequest(URL url) throws IOException {
        String jsonResponse = "";
        if (url == null) {
            return jsonResponse;
        }

        HttpURLConnection urlConnection = null;
        InputStream inputStream = null;
        try {
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.setReadTimeout(10000 /* milliseconds */);
            urlConnection.setConnectTimeout(15000 /* milliseconds */);
            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) {
                // function must handle java.io.IOException here
                inputStream.close();
            }
        }
        return jsonResponse;
    }

    private static 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();
    }
}
java json multithreading android-studio loader
1个回答
0
投票

我找到了解决方法。

这里的问题是在28-API中已弃用Loader。因此,不能使用androidx。

这里的解决方案在NewsLoader.java中:替换:import androidx.loader.content.AsyncTaskLoader;与:import android.content.AsyncTaskLoader;

如果需要使用更新的方法:请使用ViewrModels

© www.soinside.com 2019 - 2024. All rights reserved.