Android - Problem executing a asynch task and executing a thread
Can someone help me with this code? All I'm trying to do is determine whether the device's internet connection is available in a separate Connection class with an asynch task and return the result to my splash screen activity. If the connection isn't active, I want to throw a dialog alert saying it isn't active and then terminate the app. I can't get the asynch task to fire off and return a non-null result.
Splash.java:
package com.nwp;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Bundle;
public class Splash extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
initSplash();
}
private void initSplash()
{
final ProgressDialog dialog = ProgressDialog.show(this,
getResources().getString(R.string.splashCheckI开发者_开发技巧nterenetConnection),
getResources().getString(R.string.splashPleaseWait), true);
Connection.context = this;
if(!Connection.isOnline());
{
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this);
dlgAlert.setMessage(R.string.splashNoInternetConnection);
dlgAlert.setCancelable(true);
dlgAlert.setNeutralButton("Ok",
new DialogInterface.OnClickListener() {
// click listener on the alert box
public void onClick(DialogInterface arg0, int arg1) {
// the button was clicked
dialog.dismiss();
finish();
}
});
dlgAlert.create().show();
}
}
}
Connection.java:
package com.nwp;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
public class Connection {
public static Context context;
private static Boolean connectedInternet;
public static Boolean isOnline()
{
new isOnlineAsync().execute(context);
return Connection.connectedInternet;
}
// Check Internet Connection
private static class isOnlineAsync extends AsyncTask<Context, String, Boolean> {
@Override
protected Boolean doInBackground(Context... contexts) {
try {
ConnectivityManager cm = (ConnectivityManager) contexts[0].getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
boolean OnlineState = netInfo != null && netInfo.isConnected();
return OnlineState;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
Connection.connectedInternet = result;
}
}
}
Here's your problem:
new isOnlineAsync().execute(context);
return Connection.connectedInternet;
Those two lines run one after another and the AsyncTask
runs asynchronously (surprise, surprise). That means Connection.connectedInternet
is getting called before the AsyncTask
finishes. The easiest way to deal with this that I can think of is to make the AsyncTask
an inner class of the Activity, and do the if(!Connection.isOnline())
etc. stuff in the onPostExecute
. If you want to reuse the AsyncTask
in many places, you could require a callback to be passed in the constructor that would be called instead.
Update:
Actually, after coming back to this, it would make sense to me to not pass the callback in, but simply bake it into the AsyncTask
. Instead of doing:
new isOnlineAsync().execute(context);
do:
new isOnlineAsync(){
protected void onPostExecute(String result)
{
super.onPostExecute(result);
if(!Connection.isOnline())
{
// ...
}
}
}.execute(context);
Just as a side-note, start your classes with a capital letter, so call it IsOnlineAsync
instead of isOnlineAsync
.
private class BackgroundTask extends AsyncTask<String,Void,String>
{
private ProgressDialog progress;
private Context context;
public BackgroundTask(Context context)
{
this.context=context;
progress=new ProgressDialog(context);
}
@Override
protected String doInBackground(String... params)
{
ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity == null)
{
//boitealerte(this.getString("No Internet Connection"),"getSystemService rend null");
}
else
{
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null)
{
for (int i = 0; i < info.length; i++)
{
if (info[i].getState() == NetworkInfo.State.CONNECTED)
{
return true;
}
}
}
}
return false;
}
protected void onPreExecute()
{
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progress = ProgressDialog.show(context, "Checking...", "Please Wait", true,true);
}
protected void onPostExecute(String result)
{
progress.dismiss();
Toast.makeText(Update.this,"Show result here",Toast.LENGTH_LONG).show();
Update.this.finish();
}
you can return false from onPostExecute() and then check it in calling class, and show the alert dialog according to return value.
精彩评论