问题
I'm trying to check connection to the internet on Android (an actual connection, as opposed to network access) which causes NetworkOnMainThreadException
. Because of this I'm trying to move it into an AsyncTask
.
This is my isConnected()
method:
if(!checkNetwork(parent)){
return false;
}
if(!checkConnection(url)){
return false;
}
return true;
Now, I check the connection by just using if(isConnected())
but I'm getting the exception. So what I need to do is move the above method into an AsyncTask and retrieve the value it returns.
I thought perhaps I could make a global variable that'd keep track of it, but then I'm not sure if my value would be returned before or after the AsyncTask had set it.
I'm sure there are ways to do this, so I'm looking for ideas on how to do it. Any advice is appreciated!
EDIT: I've updated my code to use an AsyncTask, let me know if this looks better:
ConnectUtils.java:
public class ConnectUtils {
private static boolean hasConnected, hasChecked;
public boolean isConnected(Context parent, String url){
hasChecked = false;
this.new CheckURL(parent, url).execute();
while(!hasChecked){ }
return hasConnected;
}
private class CheckURL extends AsyncTask<Void, Void, Boolean>{
private Context parent;
private String url;
public CheckURL(Context parent, String url){
this.parent = parent;
this.url = url;
}
@Override
protected Boolean doInBackground(Void... params){
if(!checkNetwork(parent)){
return false;
}
if(!checkConnection(url)){
return false;
}
return true;
}
@Override
protected void onPostExecute(Boolean result){
super.onPostExecute(result);
hasConnected = result;
hasChecked = true;
}
}
private static boolean checkNetwork(Context parent){
ConnectivityManager conMgr = (ConnectivityManager)parent.getSystemService(Context.CONNECTIVITY_SERVICE);
if(conMgr.getActiveNetworkInfo() != null){
NetworkInfo activeInfo = conMgr.getActiveNetworkInfo();
if(!activeInfo.isConnected() || !activeInfo.isAvailable()){
return false;
}
return true;
}
return false;
}
private static boolean checkConnection(String url){
boolean responded = false;
HttpGet requestTest = new HttpGet(url);
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 3000);
HttpConnectionParams.setSoTimeout(params, 5000);
DefaultHttpClient client = new DefaultHttpClient(params);
try {
client.execute(requestTest);
responded = true;
} catch (Exception e){
e.printStackTrace();
}
return responded;
}
}
called via if(!new ConnectUtils().isConnected(this, "http://google.com"))
回答1:
here's a sample code:
new AsyncTask<Void, Void, Boolean>()
{
@Override
protected Boolean doInBackground(Void... p)
{
return isConnected();
}
@Override
protected void onPostExecute(Boolean result)
{
//this is code for the UI thread, now that it knows what is the result.
}
}.execute();
回答2:
In your AsyncTask
's onPostExecute
method, call a function in your activity to process the (now known) state of the connection. Until that method executes, your UI and/or internal logic should reflect that the state of the connection is unknown.
回答3:
Check the connection in the doInBackground()
method of AsyncTask<Url, Void, Boolean>
Params = url, progress = void (nothing) and result is a boolean.
The onPostExecute()
will return to the main thread of your application
来源:https://stackoverflow.com/questions/18433040/asynctask-to-return-a-boolean-best-way-to-implement