Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/196.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android等待AsyncTask检查服务器连接是否可用_Android_Android Asynctask_Android Networking_Networkonmainthread - Fatal编程技术网

Android等待AsyncTask检查服务器连接是否可用

Android等待AsyncTask检查服务器连接是否可用,android,android-asynctask,android-networking,networkonmainthread,Android,Android Asynctask,Android Networking,Networkonmainthread,我想要一个返回internet连接状态的方法,例如,如果没有可用连接,则返回“脱机”;如果无法连接到服务器,则返回“错误”;如果没有错误,则返回“联机” 我想从主要威胁中调用此方法,而且我无法在方法本身中发出HTTP请求,必须将其放入AsyncTask或类似的东西中。但我不知道如何操作我的代码 这几乎就是我想要的,但是我如何在try块中提取代码呢?它总是抛出NetworkOnMainThreadException public static int isOnline(Activity activ

我想要一个返回internet连接状态的方法,例如,如果没有可用连接,则返回“脱机”;如果无法连接到服务器,则返回“错误”;如果没有错误,则返回“联机”


我想从主要威胁中调用此方法,而且我无法在方法本身中发出HTTP请求,必须将其放入
AsyncTask
或类似的东西中。但我不知道如何操作我的代码

这几乎就是我想要的,但是我如何在try块中提取代码呢?它总是抛出
NetworkOnMainThreadException

public static int isOnline(Activity activity)
{
    ConnectivityManager cm = (ConnectivityManager) activity.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    int netType = 0;
    if (netInfo != null)
    {
        netType = netInfo.getType();
        if (netInfo.isAvailable() && netInfo.isConnected())
        {
            if (netType == ConnectivityManager.TYPE_WIFI || netType == ConnectivityManager.TYPE_MOBILE)
            {
                try
                {
                    URL myUrl = new URL(HTTP_HOST);
                    URLConnection connection = myUrl.openConnection();
                    connection.setConnectTimeout(5000);
                    connection.connect();
                    return INTERNET_CONNECTIVITY_ONLINE;
                } catch (IOException e)
                {
                    return INTERNET_CONNECTIVITY_ERROR;
                }
            }
        }
    }
    return INTERNET_CONNECTIVITY_OFFLINE;
}
编辑:

我忘了说我的HTTP_主机需要HTTP身份验证。也许我也必须为请求添加这些身份验证

编辑:

想要这样的东西:

public static int isOnline(Activity activity)
{
    ConnectivityManager cm = (ConnectivityManager) activity.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    int netType = 0;
    if (netInfo != null)
    {
        netType = netInfo.getType();
        if (netInfo.isAvailable() && netInfo.isConnected())
        {
            if (netType == ConnectivityManager.TYPE_WIFI || netType == ConnectivityManager.TYPE_MOBILE)
            {
                MyAsyncTask as = new MyAsyncTask();
                return as.execute("") == true ? INTERNET_CONNECTIVITY_ONLINE : INTERNET_CONNECTIVITY_ERROR;
            }
        }
    }
    return INTERNET_CONNECTIVITY_OFFLINE;
}

您可以在任何时候使用它,只需制作您自己的InternetDetector或任何您想称之为类的东西:

public class InternetDetector{

    private InternetDetector(){ }

    public static InternetDetector getInstance(){
        return new InternetDetector();
    }

    public boolean isOnline(){
        ConnectivityManager cm = (ConnectivityManager) activity.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        int netType = 0;
        if (netInfo != null){
            netType = netInfo.getType();
            if (netInfo.isAvailable() && netInfo.isConnected()){
                if (netType == ConnectivityManager.TYPE_WIFI || netType ==       ConnectivityManager.TYPE_MOBILE){
                return true;
                }
            }
        }
        return false;

    }
}

一旦你创建了这个类,你可以在任何地方调用它。只需使用静态工厂获取实例并检查可用性

    if(InternetDetector.getInstance().isOnline()){
          //do your internt stuff here
    }

你可以在这个if语句中执行任何需要互联网的代码,因为如果它是真的,那么外面就有互联网

好吧,我想我们都误解了这个问题

你想在应用程序中的所有其他呼叫之前先呼叫服务器以确定其是否可用,我说的对吗

解决方案:

1.)您的服务器可能随时停机。为什么不直接查询您希望工作的端点,然后在需要时处理5xx响应呢。这将节省您的往返行程,并大大提高稳定性

2.)为什么不使用回调?如果您在UI thead上,请使用回调。安卓thrwos
NetworkOnMainTHread
的原因是因为它阻塞了——这意味着您的整个UI将挂起。如果你使用一个
AsyncTask
,然后阻塞(或者你说的“等待”)直到它完成,你只能绕过android的内置检查-如果UI线程挂起,你仍然会有一个有问题的应用程序

AsyncTask的设计目的是使回调变得容易-方法
onPostExecute
在UI thead上运行,而
doInBackground
在后台线程上运行。这很好。将服务器启动后要执行的代码放入
postExecute
位,在
doInBackground
中执行http

3.)好的,让我们假设出于某种原因(这可能是完全正确的;)您需要将在
AsyncTask
中启动的调用转换为阻塞调用? 在这种情况下,您需要覆盖
AsyncTask
中的
onPostExecute
,并使用
信号量

在半Java代码中:

// in your blocking method:
Semaphore myAsyncWaiterSemaphore = new Semaphore(0);
AsyncTask myAsyncTask = new MyAsyncTask(myAsyncWaiterSemaphore); // take the semaphore in the ctor and set it as a field.
myAsyncWaiterSemaphore.acquire();

// in your async task:
onPostExecute(your-args...) {
    this.mSemaphore.acquire(); // you've passed this in as a field.
}
好了。然后,您的响应需要在某个地方为响应代码设置一个getter和setter来检查结果

但请不要这样做,除非你确定你需要它。是的,(3)是你等待http异步加载完成的方式,如果你想在阻塞方法中完成的话,但是最好使用回调并在第一次回调启动后关闭应用程序的其余http

我意识到这需要考虑很多,所以请发表评论,这样我才能澄清


最佳。

看这个:谷歌I/O 2010-安卓REST客户端应用程序

并阅读以下内容:


概要:您不应该从异步任务下载任何内容。这应该在IntentService中完成,或者更好地说,在带有ContentProvider的SyncAdatper中完成。

“我无法在方法本身中发出HTTP请求,必须将其放入异步任务或类似的任务中”您的问题是我如何在异步任务中执行HTTP?因为这就是为什么你会有例外。你的主机是什么?试试google.com?嗯,不,我不知道如何启动
AsyncTask
并等待其结果在
isOnline
方法中返回。检查这个:通过使用java储备充足的并发库?啊,我明白了。您想知道如何等待?但这只查找Internet连接,而不是服务器是否可用。请经常调用
isOnline
方法,例如在ActionBar中显示联机/脱机图标之前。如果我在线(并且服务器可用),我会启动一个
AsyncTask
来下载新数据。正因为如此,我想有一个中心方法,它说:你在线,服务器可用。用户不应该注意到,当我寻找这个。
myAsyncTask.get(3000,TimeUnit.ms)
不是一个好选项吗?请不要误解我的意思:只有当我通常使用
AsyncTasks
时,
isOnline
才能识别服务器可用性,我会向用户显示一个
ProgressDialog
。也许我应该测试一下你的选项3。现在你告诉我更多的信息,而这取决于你的设计,听起来你实际上需要一种叫做“闩锁”的东西。基本上,在您的方法中,您的“下载新数据的异步任务”(以及您喜欢的任何其他任务)被触发,您需要等待一个锁存器(例如,
CountdownLatch
),该锁存器会在您触发后面的任务之前阻塞。然后,在UI线程上,启动一个异步任务来检查服务器的可用性。在它的
postExecute
中,获取对该闩锁的引用并倒计时。然后,就像施了魔法一样,你所有的其他任务都会启动。