问题
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
andJSONArray
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