Ping website URL before loading it in WebView in A

2019-07-31 11:16发布

问题:

Before loading a website in WebView, I want to check the URL and make sure that it loads. If it does, show the WebView; if not, show another View with a message.

The idea is to check if the website can be loaded and depending on the response show either the "Website cannot be loaded" screen or show the WebView with URL loaded.

I have already checked if the connection is available, so no need to worry about that.

Need to support API 25+.

回答1:

My solution below is trying to do two things:

  1. Using AsyncTask "ping" a website and then

  2. By passing context from MainActivity, call a function to show WebView (using WeakReference here to achieve that)

class MainActivity : AppCompatActivity() {
private var websiteURL = "https://www.google.com"

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // ...
    webView.webViewClient = WebViewClient()
}

// I called this function after checking that there is Internet connection
private fun connectionResponseFunction(): String {
    return if (isConnected) {
        // *** is connected
        // pass in "this" context from MainActivity
        val downloadData = CheckLink(this)
        downloadData.execute(websiteURL)
    } else {
      // *** not connected
    }
}

private fun showWebView() {
    webView.loadUrl(websiteURL)
}

companion object {
    class CheckLink internal constructor(context: MainActivity) : AsyncTask<String, Void, String>() {
      // Needed if you want to use webView or anything else from MainActivity
        private val activityReference: WeakReference<MainActivity> = WeakReference(context)

        override fun onPostExecute(result: String?) {
            super.onPostExecute(result)
            val activity = activityReference.get()
            if (activity == null || activity.isFinishing) return

            if (result == "success") {
                // URL loaded, show webView
                activity.showWebView()
            } else {
                // URL didn't load
            }
        }

        override fun doInBackground(vararg url: String?): String {
            val linkLoaded = loadLink(url[0])
            if (!linkLoaded) {
                return "failure"
            }
            return "success"
        }

        private fun loadLink(urlPath: String?): Boolean {
            try {
                val url = URL(urlPath)
                val connection: HttpURLConnection = url.openConnection() as HttpURLConnection
                connection.setRequestProperty("Connection", "close")
                connection.connectTimeout = 3000
                connection.connect()

                val response = connection.responseCode

                // 200 for success
                return if (response == 200) {
                    true
                } else {
                    false
                }
            } catch (e: Exception) {
              // Handle exceptions
                when (e) {
                    is MalformedURLException -> "loadLink: Invalid URL ${e.message}"
                    is IOException -> "loadLink: IO Exception reading data: ${e.message}"
                    is SecurityException -> { e.printStackTrace()
                        "loadLink: Security Exception. Needs permission? ${e.message}"
                    }
                    else -> "Unknown error: ${e.message}"
                }
            }
            return false  // Error
        }
    }
}
}

I'm quite new to Android and Kotlin, so I'm open to any suggestions to make it better.

I could not find any recent code that works for API 25+.