简体   繁体   English

如何在Android上正确使用AsyncTask?

[英]How to properly use AsyncTask on Android?

I need help with checking if the phone my app is running on is connected to the Internet. 我需要检查我的应用程序正在运行的电话是否已连接到Internet的帮助。 I started with pinging an IP to check connection. 我从ping IP检查连接开始。 It looked like this: 它看起来像这样:

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

However, it allways threw the NetworkOnMainThreadException, so I used AsyncTask: 但是,它始终引发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;
        }
    }
}

Is this code correct? 此代码正确吗? Because I don't know how to call it. 因为我不知道该怎么称呼。 I tried: 我试过了:

new CheckConnectionTask().execute();

Is anything missing there? 那里缺少什么吗? Because it doesn't work. 因为它不起作用。 Also please note that I've seen a lot of previous questions, but I didn't find any answer to this problem, so I asked my own question. 另外请注意,我之前已经看过很多问题,但是没有找到任何答案,所以我问了自己一个问题。 If you've seen an answered question that can solve my problem you can link it here, but keep in mind that I am not experienced with Android or Java, so it might be unclear to me. 如果您看到可以解决我的问题的已回答问题,则可以在此处链接它,但请记住,我对Android或Java并不熟悉,因此我可能不清楚。 I would preffer correct code as an answer, and a brief explaination why my didn't work. 我会提供正确的代码作为答案,并简要解释为什么我的代码无法正常工作。 Also, I need to know if the phone is connected to the INTERNET, not a NETWORK, so ConnectivityManager won't wor for me. 另外,我需要知道电话是否连接到INTERNET,而不是NETWORK,所以ConnectivityManager对我来说并不麻烦。

EDIT - thank you all for your answers. 编辑-谢谢大家的回答。 First of all, I have all the permissions required. 首先,我具有所需的所有权限。 Also, I can't get any results currently, as Android Studio highlights the following code: 另外,由于Android Studio突出显示以下代码,我目前无法获得任何结果:

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

As incorrect and it simply won't let me call the function. 由于不正确,它根本不让我调用该函数。 What is wrong with it? 怎么了 Is it missing any parameters? 是否缺少任何参数? Because I've defined params as Void so that seems illogical. 因为我已将params定义为Void,所以这似乎不合逻辑。

Edit 2 - I've used onPostExecute, as suggested by @vandaics, and it looks like this now: 编辑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;
    }
}

It works, and I call it when calling the onCreate method: 它有效,我在调用onCreate方法时调用它:

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

It works, my apps checks if the Internet is connected and reacts properly. 它可以正常工作,我的应用程序会检查Internet是否已连接并做出正确反应。 If you think something might not work, or there is an easier way to do that, let me know. 如果您认为某些方法可能不起作用,或者有更简单的方法可以这样做,请告诉我。 Many thanks to you guys, especially @vandaics and @Sunil. 非常感谢你们,特别是@vandaics和@Sunil。 Also, do I need to use superclass like here?: 另外,我是否需要像这样使用超类?:

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

What does it do and is it necessary? 它是做什么的并且有必要吗?

You currently are not seeing anything because you have no log statements or you are not really checking for anything. 您目前看不到任何内容,因为您没有日志语句,或者您实际上没有检查任何内容。

The call 通话

new CheckConnectionTask().execute() 新的CheckConnectionTask()。execute()

is running the AsyncTask. 正在运行AsyncTask。 It's just that there is no output for the task to show. 只是没有任何输出可显示任务。

you can check for the output and see if it is what you want. 您可以检查输出,看看是否是您想要的。

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

EDIT: The call: 编辑:呼叫:

new CheckConnectionTask().execute() 新的CheckConnectionTask()。execute()

returns an instance of the AsyncTask that it is executing and not a Boolean (although you do specify that Boolean should be the output). 返回正在执行的AsyncTask实例,而不是布尔值(尽管您确实指定应将布尔值作为输出)。 Hence you are seeing a compilation error here. 因此,您在这里看到编译错误。 AsyncTask was designed to be self contained - it does everything it's supposed to do and then terminates. AsyncTask被设计为自包含的-它完成了它应该做的所有事情,然后终止。 If you do have to modify a class level instance variable (from the class that contains the AsyncTask as an inner task) that can be done but not suggested. 如果确实必须修改一个类级别的实例变量(来自包含AsyncTask作为内部任务的类),则可以执行但不建议这样做。

If you are going to use AsyncTaks you're missing the onPostExecute method: 如果要使用AsyncTaks ,则缺少onPostExecute方法:

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

You can also add the optional onProgressUpdate method: 您还可以添加可选的onProgressUpdate方法:

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

Then to execute you do: 然后执行以下操作:

new DownloadFilesTask().execute(); 新的DownloadFilesTask()。execute();

Here is a good example you can use: http://developer.android.com/reference/android/os/AsyncTask.html 这是一个可以使用的好示例: http : //developer.android.com/reference/android/os/AsyncTask.html

to check if the internet connection is available, you can do this: 要检查互联网连接是否可用,您可以执行以下操作:

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

You can't call 你不能打电话

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

the return value of excute() is not what you want. excute()的返回值不是您想要的。 If you want use asyntask you can set a boolean variable in onPostExecute(...) : 如果要使用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;
}
}

But, I never use this approach to get status of internet connection, beacause I must run this asyntask before everything to get exact status. 但是,我从不使用这种方法来获取Internet连接的状态,因为我必须先运行此异步任务,然后才能获取所有状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM