从线程中获取值

时间:2014-06-13 14:01:50

标签: android multithreading

我尝试使用以下代码片段检查互联网连接:

     private static boolean done;

 public static boolean isInternetConnected(Context context) {
    boolean networkConnected = false;
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(
            Context.CONNECTIVITY_SERVICE);

    NetworkInfo wifiNetwork = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
    if (wifiNetwork != null && wifiNetwork.isConnected()) {
        networkConnected = true;
    }

    NetworkInfo mobileNetwork = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
    if (mobileNetwork != null && mobileNetwork.isConnected()) {
        networkConnected = true;
    }

    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    if (activeNetwork != null && activeNetwork.isConnected()) {
        networkConnected = true;
    }

    if(networkConnected) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    HttpURLConnection urlc = (HttpURLConnection) (new URL("http://www.google.com").openConnection());
                    urlc.setRequestProperty("User-Agent", "Test");
                    urlc.setRequestProperty("Connection", "close");
                    urlc.setConnectTimeout(1500);
                    urlc.connect();
                    done = (urlc.getResponseCode() == 200);
                    //1st
                    Log.d(TAG, "done =" + done);
                } catch (Exception e) {
                    Log.e(TAG, "Error checking internet connection", e);
                }

            }
        });

        thread.start();
        //2nd 
        Log.d(TAG, "after start done =" + done);
        return done;
    }

    return networkConnected;

}

问题是"完成"在线程" // 1st"是"是的:但在线程" // 2nd"是"假"。我不知道这里有什么问题?有人可以解释这种奇怪的行为吗?

3 个答案:

答案 0 :(得分:1)

您正在启动一个在后台运行的线程,需要一段时间才能完成。对thread.start()的调用将立即返回,因此当您在done检查2nd的值时,它仍为false,因为后台线程尚未完成其工作。< / p>

如果您不希望在完成测试HTTP请求之前返回方法,请不要将其放在线程中。

附注 - 请勿对Google进行投票以测试​​互联网连接 - 这有点粗鲁!

答案 1 :(得分:0)

当线程在后台完成工作时,您需要通知。有关如何通知您的mainUI的解决方案,请参阅我的其他答案。

How to return an object from the asynctask to the main class in android

答案 2 :(得分:0)

我可以在您的代码中看到两个问题。第一个是正如其他海报所指出的那样,thread.start()立即返回,所以你的“之后”部分将在你的衍生线程之前实际执行。

第二个问题是,由于done的值是在单独的线程中设置的,因此无法保证值的更改在主线程中可见。因此,除了修改其他人建议的程序逻辑外,您还需要在声明布尔值volatile时使用done关键字。