Is there a better way to execute this code (load multiple urls)?

橙三吉。 提交于 2019-12-12 03:33:59

问题


my code is working but when i launch the app, it is not fluent, i was wondering if there is a better way to make this code work or more cleaner to improve quickness ? Please any answer is welcome. Thank you.

public class MainActivity extends AppCompatActivity {

    public static final String TAG = MainActivity.class.getSimpleName();
    private List<Articles> mArticlesList;
    private RecyclerView mRecyclerView;
    private String[] mUrl = new String[]{"https://newsapi.org/v1/articles?source=buzzfeed&apiKey=5e08eafaefd44d14ad70ceea834c16bb"
            , "https://newsapi.org/v1/articles?source=the-verge&apiKey=5e08eafaefd44d14ad70ceea834c16bb"
            , "https://newsapi.org/v1/articles?source=the-lad-bible&apiKey=5e08eafaefd44d14ad70ceea834c16bb"};

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

        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);

        for (int i = 0; i < mUrl.length; i++) {
            getInfos(mUrl[i]);
        }
    }

    private void getInfos(String url) {

        if (isNetworkAvailable()) {

            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder().url(url).build();

            client.newCall(request).enqueue(new Callback() {

                @Override
                public void onResponse(Call call, Response response) throws IOException {

                    try {
                        String jsonData = response.body().string();
                        if (response.isSuccessful()) {
                            Log.v(TAG, jsonData);

                            getMultipleUrls(jsonData);

                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    getCurrentArticles(mArticlesList);
                                }
                            });
                        } else {
                            alertUserAboutError();
                        }
                    } catch (IOException | JSONException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onFailure(Call call, IOException e) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                        }
                    });
                    alertUserAboutError();
                }
            });
        } else {
            alertUserAboutError();
        }

    }

    private void getMultipleUrls(String jsonData) throws JSONException {
        if (mArticlesList == null) {
            mArticlesList = getArticleForecast(jsonData);
        } else {
            mArticlesList.addAll(getArticleForecast(jsonData));
        }
    }

    private void getCurrentArticles(List<Articles> articles) {

        ArticleAdapter articleAdapter = new ArticleAdapter(this, articles);

        mRecyclerView.setAdapter(articleAdapter);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(layoutManager);
    }

    private boolean isNetworkAvailable() {
        ConnectivityManager manager = (ConnectivityManager)
                getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = manager.getActiveNetworkInfo();
        boolean isAvailable = false;
        if (networkInfo != null && networkInfo.isConnected()) {
            isAvailable = true;
        }
        return isAvailable;
    }

    private void alertUserAboutError() {
        AlertDialogFragment alertDialogFragment = new AlertDialogFragment();
        alertDialogFragment.show(getFragmentManager(), "error_dialog");
    }

    private List<Articles> getArticleForecast(String jsonData) throws JSONException {
        JSONObject forecast = new JSONObject(jsonData);
        JSONArray articles = forecast.getJSONArray("articles");

        List<Articles> listArticles = new ArrayList<>(articles.length());

        for (int i = 0; i < articles.length(); i++) {
            JSONObject jsonArticle = articles.getJSONObject(i);
            Articles article = new Articles();

            String urlImage = jsonArticle.getString("urlToImage");

            article.setTitle(jsonArticle.getString("title"));
            article.setDescription(jsonArticle.getString("description"));
            article.setImageView(urlImage);
            article.setArticleUrl(jsonArticle.getString("url"));

            listArticles.add(i, article);
        }

        return listArticles;
    }

回答1:


Ok, so my problem is that every time that I call getInfos method I create a new client..

This is exactly your issue; and there are a few ways of solving it.

The fastest way to solve your issue is to just create the OkHttpClient in your onCreate method as a global variable. You may also want to only check if the network is available a single time.

public class MainActivity extends AppCompatActivity {

    private static final String[] mUrls = new String[] {
        "https://newsapi.org/v1/articles?source=buzzfeed&apiKey=5e08eafaefd44d14ad70ceea834c16bb",
        "https://newsapi.org/v1/articles?source=the-verge&apiKey=5e08eafaefd44d14ad70ceea834c16bb",
        "https://newsapi.org/v1/articles?source=the-lad-bible&apiKey=5e08eafaefd44d14ad70ceea834c16bb"
    };

    private RecyclerView mRecyclerView;
    private OkHttpClient mOkHttpClient;
    private ConnectivityManager mConnectivityManager;

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

        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        mOkHttpClient = new OkHttpClient();

        loadData();
    }

    private void loadData() {
        if (isNetworkAvailable()) {
            for (String url : mUrls) {
                createRequest(url);
            }
        }
    }

    private void createRequest(String url) {
        Request request = new Request.Builder().url(url).build();
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
                // Your response implementation
            }

            @Override
            public void onFailure(Call call, IOException exception) {
                // Your failure implementation
            }
        });
    }

    private boolean isNetworkAvailable() {
        NetworkInfo info = mConnectivityManager.getActiveNetworkInfo();
        return info != null && info.isConnected();
    }

}

An even more beneficial way to solve this issue (if you use OkHttp in more than one Activity) is to only create a single OkHttpClient for your entire application. Though, this will require dependency injection, which the Android framework can make a bit more complicated; this is a good article that covers the basics.


Also, to make your life even easier, I would recommend a few other libraries that compliment OkHttp. It may take a while to learn some of them, but each will make working with network code significantly easier on Android. You don't need all of them either, you can start with one and work up from there.

  • Retrofit builds upon OkHttp (it is also by Square), and makes interacting with APIs a breeze.

  • Moshi is a JSON parser (also by Square), that works with Retrofit so you can avoid the cumbersome JSONObject and JSONArray code (Google's Gson also works with Retrofit).

  • And finally; RxJava and RxAndroid will make asynchronous calls even easier; you can even zip all three of your requests together, so you receive the results all at once!



来源:https://stackoverflow.com/questions/42227239/is-there-a-better-way-to-execute-this-code-load-multiple-urls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!