简体   繁体   English

检查网址是否存在

[英]Checking if url exists

For my project I need to check a URL to see if it exists or not. 对于我的项目,我需要检查一个URL以查看它是否存在。 So I created a HttpURLConnection and connected to the url and wait for the response code. 因此,我创建了一个HttpURLConnection并连接到url,然后等待响应代码。 Since I can't use that HttpURLConnection in my Main Thread, i had to move it to an AsyncTask and let it run on a separate Thread. 由于我无法在主线程中使用该HttpURLConnection,因此必须将其移至AsyncTask并使其在单独的线程上运行。

This is what my code for that AsyncTask looks like (only the important parts): 这是我的AsyncTask代码(仅重要部分):

private class URLExists extends AsyncTask<String, Void, Boolean> {

    protected Boolean doInBackground(String... urls)
    {
        boolean isValid = false;

        try
        {
            URL myurl = new URL(urls[0]);
            HttpURLConnection.setFollowRedirects(false);

            HttpURLConnection connection = (HttpURLConnection) myurl.openConnection();
            connection.setUseCaches(true);
            connection.setRequestMethod("HEAD");
            connection.connect();
            int code = connection.getResponseCode();

            ...

            connection.disconnect();

            if(code != 404)
                isValid = true;

            else
                isValid = false;
        }

            ...
        return isValid;
    }

    protected void onPostExecute(Boolean isValid)
    {
        isTrue = isValid;
    }
}

So basically i then get a boolean value isTrue which tells me if the url is valid. 所以基本上我然后得到一个布尔值isTrue ,它告诉我该URL是否有效。 When I run this i get the right results, everything works. 当我运行此程序时,我得到正确的结果,一切正常。

But now, when i execute this AsyncTask, it runs parallel to my main Thread, obviously. 但是现在,当我执行此AsyncTask时,它显然与我的主线程平行运行。

I have this code: 我有以下代码:

new URLExists().execute("https://www.example.com");
if(isTrue)
{
    myButton.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                //Do Something
            }
        });
}

Since my AsyncTask runs parallel, my Main Thread executes the next operation without waiting for the result of the AsyncTask. 由于我的AsyncTask是并行运行的,因此我的主线程无需等待AsyncTask的结果即可执行下一个操作。 Since isTrue is false by default, the if statement never runs. 由于默认情况下isTruefalse ,因此if语句永远不会运行。

Of course i know about the protected void onPostExecute() in the AsyncTask, but does that mean that all the code that follows in my main Thread has to be in that function in the parallel Thread? 当然,我知道AsyncTask中protected void onPostExecute() ,但这是否意味着我主线程中的所有代码都必须在并行线程的该函数中? It all depends on the outcome of the URL check. 这完全取决于URL检查的结果。

I know about the .get() method, but that freezes my MainThread and the UI, so that's not really an option for me. 我知道.get()方法,但这冻结了我的MainThread和UI,因此这对我来说不是一个选择。

Is there any other way of making the Main thread wait for the AsyncTask? 还有其他方法可以让主线程等待AsyncTask吗? I know the defeats the purpose of the AsyncTask, but all I want is to check if the URL exists and I can only do checks in an AsyncTask. 我知道失败了AsyncTask的目的,但是我只想检查URL是否存在,并且我只能在AsyncTask中进行检查。

You don't need multithread for your task. 您不需要多线程来执行任务。 All what you need is to check that url is available. 您所需要做的就是检查网址是否可用。 Right? 对? Of course it may take some time and you have to wait this time in your main thread. 当然,这可能需要一些时间,您必须在主线程中等待这个时间。 That's right. 那就对了。 But you still need to wait. 但是您仍然需要等待。 Don't create unnecessary complexity. 不要造成不必要的复杂性。 Just read url, get response code, validate it, check for timeout exception and you are good to go. 只需阅读url,获取响应代码,对其进行验证,检查超时异常,就可以了。

We need to look at the specification of AsyncTask. 我们需要查看AsyncTask的规范。 Typically in any asynchronous method you have a callback function that lets you know the background operation has completed. 通常,在任何异步方法中,都有一个回调函数,让您知道后台操作已完成。 In the case of Android it is onPostExecute() 如果是Android,则为onPostExecute()

It can be found here. 在这里能找到它。 http://developer.android.com/reference/android/os/AsyncTask.html http://developer.android.com/reference/android/os/AsyncTask.html

When an asynchronous task is executed, the task goes through 4 steps: 当执行异步任务时,该任务将经历4个步骤:

  1. onPreExecute() , invoked on the UI thread before the task is executed. onPreExecute() ,在执行任务之前在UI线程上调用。 This step is normally used to setup the task, for instance by showing a progress bar in the user interface. 此步骤通常用于设置任务,例如,通过在用户界面中显示进度栏。

  2. doInBackground(Params...) , invoked on the background thread immediately after onPreExecute() finishes executing. doInBackground(Params...) ,在onPreExecute()完成执行后立即在后台线程上调用。 This step is used to perform background computation that can take a long time. 此步骤用于执行可能需要很长时间的后台计算。 The parameters of the asynchronous task are passed to this step. 异步任务的参数将传递到此步骤。 The result of the computation must be returned by this step and will be passed back to the last step. 计算结果必须通过此步骤返回,并将传递回最后一步。 This step can also use publishProgress(Progress...) to publish one or more units of progress. 此步骤还可以使用publishProgress(Progress ...)发布一个或多个进度单位。 These values are published on the UI thread, in the onProgressUpdate(Progress...) step. 这些值在onProgressUpdate(Progress ...)步骤中发布在UI线程上。

  3. onProgressUpdate(Progress...) , invoked on the UI thread after a call to publishProgress(Progress...). onProgressUpdate(Progress...) ,在调用publishProgress(Progress ...)之后在UI线程上调用。 The timing of the execution is undefined. 执行的时间是不确定的。 This method is used to display any form of progress in the user interface while the background computation is still executing. 此方法用于在后台计算仍在执行时在用户界面中显示任何形式的进度。 For instance, it can be used to animate a progress bar or show logs in a text field. 例如,它可用于为进度栏设置动画或在文本字段中显示日志。

  4. onPostExecute(Result) , invoked on the UI thread after the background computation finishes. onPostExecute(Result) ,在后台计算完成后在UI线程上调用。 The result of the background computation is passed to this step as a parameter. 后台计算的结果作为参数传递到此步骤。

For your specific case you might want to do something like this.. 对于您的特定情况,您可能想要执行以下操作。

yourAsyncTask{
   @Override
   protected Boolean doInBackground(Void... params){
        // CHECK YOUR URL HERE
   }
   .
   .
   .
   @Override
   public void onPostExecute(Result result){
      if(isTrue) {
        myButton.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            //Do Something
         }
        });
      }
   }
}

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

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