如何在Android上正确使用AsyncTask?

时间:2015-04-17 21:30:28

标签: java android android-asynctask android-networking android-internet

我需要帮助检查我的应用运行的手机是否已连接到互联网。我开始ping IP以检查连接。它看起来像这样:

    protected Boolean checkInternetConnection(Void... params) {
        try {
            InetAddress ipAddr = InetAddress.getByName("https://www.google.com");

            if (!ipAddr.isReachable(10000)) {
                return false;
            } else {
                return true;
            }

        } catch (Exception e) {
            Log.e("exception", e.toString());
            return false;
        }
    }
}

然而,它始终抛出NetworkOnMainThreadException,所以我使用了AsyncTask:

private class CheckConnectionTask extends AsyncTask<Void, Void, Boolean> {
    @Override
    protected Boolean doInBackground(Void... params) {
        try {
            InetAddress ipAddr = InetAddress.getByName("https://www.google.com");

            if (!ipAddr.isReachable(10000)) {
                return false;
            } else {
                return true;
            }

        } catch (Exception e) {
            Log.e("exception", e.toString());
            return false;
        }
    }
}

这段代码是否正确?因为我不知道怎么称呼它。我试过了:

new CheckConnectionTask().execute();

那里有什么遗漏?因为它不起作用。另请注意,我之前已经看过很多问题,但我没有找到任何问题的答案,所以我问自己的问题。如果你已经看到一个可以解决我的问题的答案问题,你可以在这里链接它,但请记住,我没有Android或Java的经验,所以我可能不清楚。我会把正确的代码作为答案,并简要解释为什么我没有工作。另外,我需要知道手机是否连接到INTERNET,而不是网络,所以ConnectivityManager对我来说不是很好。

编辑 - 谢谢大家的回答。首先,我拥有所需的所有权限。此外,我目前无法获得任何结果,因为Android Studio突出显示以下代码:

Boolean internetConnection;
internetConnection = new     CheckConnectionTask().execute();

由于不正确,它只是不让我调用该功能。这有什么问题?它缺少任何参数吗?因为我将params定义为Void,所以这似乎是不合逻辑的。

编辑2 - 我已经按照@vandaics的建议使用了onPostExecute,现在看起来像这样:

private class CheckConnectionTask extends AsyncTask<Void, Void, Boolean> {
    @Override
    protected Boolean doInBackground(Void... params) {
        try {
            InetAddress ipAddr = InetAddress.getByName("google.com");

            if (!ipAddr.isReachable(10000)) {
                return false;
            } else {
                return true;
            }

        } catch (Exception e) {
            Log.e("exception", e.toString());
            return false;
        }
    }
    @Override
    protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);
        internetConnection = result;
    }
}

它有效,我在调用onCreate方法时调用它:

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

它有效,我的应用程序检查互联网是否已连接并做出正确反应。如果你认为某些东西可能不起作用,或者有更简单的方法,请告诉我。非常感谢你们,特别是@vandaics和@Sunil。另外,我是否需要像这里一样使用超类?:

    @Override
    protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);
        internetConnection = result;
    }

它做了什么,是否有必要?

3 个答案:

答案 0 :(得分:3)

您目前没有看到任何内容,因为您没有日志声明,或者您没有真正检查任何内容。

电话

  

new CheckConnectionTask()。execute()

正在运行AsyncTask。只是没有要显示的任务的输出。

您可以检查输出并查看它是否是您想要的。

private class CheckConnectionTask extends AsyncTask<Void, Void, Boolean> {
    @Override
    protected Boolean doInBackground(Void... params) {
        try {
            InetAddress ipAddr = InetAddress.getByName("https://www.google.com");

            if (!ipAddr.isReachable(10000)) {
                return false;
            } else {
                return true;
            }

        } catch (Exception e) {
            Log.e("exception", e.toString());
            return false;
        }
    }

    @Override
    public void onPostexecute(Boolean result) {
        // TO DO on the UI thread
        Log.i("AsyncTask", "Result = " + result");
    }
}

编辑:电话:

  

new CheckConnectionTask()。execute()

返回它正在执行的AsyncTask的实例而不是布尔值(尽管你指定布尔值应该是输出)。因此,您在这里看到了编译错误。 AsyncTask被设计为自包含 - 它执行它应该做的所有事情然后终止。如果你必须修改类级实例变量(从包含AsyncTask作为内部任务的类),可以完成但不建议。

答案 1 :(得分:0)

如果您要使用AsyncTaks,则错过了onPostExecute方法:

 protected void onPostExecute(Boolean result) {
     //your code here
 }

您还可以添加可选的onProgressUpdate方法:

 protected void onProgressUpdate(Integer... progress) {
    //do something on update
 }

然后执行:

new DownloadFilesTask()。execute();

以下是您可以使用的一个很好的示例:http://developer.android.com/reference/android/os/AsyncTask.html

答案 2 :(得分:0)

要检查互联网连接是否可用,您可以这样做:

private boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting();
    //return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}

你不能打电话

Boolean internetConnection;
internetConnection = new CheckConnectionTask().execute();

excute()的返回值不是您想要的。如果你想使用asyntask,你可以在onPostExecute(...)中设置一个布尔变量:

private boolean isConnect = false;
private class CheckConnectionTask extends AsyncTask<Void, Void, Boolean> {
@Override
protected Boolean doInBackground(Void... params) {
    try {
        InetAddress ipAddr = InetAddress.getByName("https://www.google.com");

        if (!ipAddr.isReachable(10000)) {
            return false;
        } else {
            return true;
        }

    } catch (Exception e) {
        Log.e("exception", e.toString());
        return false;
    }
}
@Override
protected void onPostExecute(Boolean result) {
    super.onPostExecute(aVoid);
    isConnect = result;
}
}

但是,我从来没有使用这种方法来获取互联网连接的状态,因为我必须在所有事情之前运行这个asyntask才能获得准确的状态。