有没有更好的方法来执行此代码(加载多个网址)?

时间:2017-02-14 13:19:34

标签: android performance arraylist android-asynctask android-recyclerview

我的代码正在运行,但是当我启动应用程序时,它不流畅,我想知道是否有更好的方法使这个代码工作或更清洁,以提高速度?欢迎任何答复。谢谢。

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 个答案:

答案 0 :(得分:0)

  

好的,所以我的问题是每次我调用getInfos方法I   创建一个新客户..

完全你的问题;并且有几种方法可以解决它。

解决问题的最快方法是在OkHttpClient方法中创建onCreate作为全局变量。您可能还想仅检查一次网络是否可用。

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

}

解决此问题的更有效方法(如果您在多个Activity中使用OkHttp)是仅为整个应用程序创建一个OkHttpClient。虽然,这将需要依赖注入,Android框架可以使其更复杂; this is a good article涵盖了基础知识。

另外,为了让您的生活更轻松,我会推荐一些其他赞美OkHttp的库。学习其中一些可能需要一段时间,但每个都将使得在Android上使用网络代码变得更加容易。你不需要所有这些,你可以从一个开始,然后从那里开始工作。

  • Retrofit建立在OkHttp之上(它也是Square),并且 使与API的交互变得轻而易举。

  • Moshi是一个JSON解析器(也是Square),可以使用 改造,以便您可以避免繁琐的JSONObjectJSONArray 代码(Google的Gson也适用于Retrofit。)

  • 最后; RxJavaRxAndroid会异步 电话更容易;您甚至可以zip提出所有三项请求 在一起,所以你一次收到结果!