- Home /
Any way around WWW timeout on Android?
I'm working on a project that requires scene changes to be remote-controlled. My thought was to have the app call a WWW every few seconds, and change the scene based on the response. I'm running into issues, though: WWW tends to run into errors on a regular basis on android, and then it spends 60 seconds waiting to time-out before it will start another WWW and be able to get the scene change command. I've tried stopping the coroutine, disposing of the WWW, and starting a second coroutine, but nothing works on Android. Can anyone suggest a better way of going about this?
My code thus far:
void Update(){
if(Time.time - lastCheck > 2F && runRupdater == true){
StartCoroutine(getCurrentScene ());
}
}
//Get the current scene, then continue to check every two seconds.
IEnumerator getCurrentScene (){
float thisCheck = Time.time;
lastCheck = Time.time;
string urlToCheck = "http://myurl/where.php?pi="+whichPresentation;
WWW getScene = new WWW(urlToCheck);
yield return getScene;
if(Time.time - thisCheck > 3F){
getScene.Dispose();
yield break;
}
if(getScene.text != "null"){
if(currentScene != int.Parse(getScene.text)){
int.TryParse(getScene.text, out currentScene);
StartCoroutine(ActOnScene ());
}
}
}
Answer by peacefulshade · Jun 26, 2014 at 12:24 PM
If anyone stumbles on this, on android devices the WWW.Dispose method won't return immediately after called but will hang until the timeout is done or an error occurs; if the connection is slow (on the subway 4 example) this can lasts up to 60 seconds.
What I ended up doing was creating a WWW disposer that disposes WWWs when they are done; this prevents the device from freezing.
public class WWWDisposer : MonoBehaviour
{
private List<WWW> m_wwwsToDispose = new List<WWW>();
void Awake()
{
GameObject.DontDestroyOnLoad(gameObject);
}
public void AddWWWToDispose(WWW _toDispose)
{
m_wwwsToDispose.Add(_toDispose);
}
void Update()
{
for(int i = 0; i < m_wwwsToDispose.Count; i++)
{
if(m_wwwsToDispose[i].isDone)
{
Debug.Log("[TRS] WWW disposed after natural error or completion: " + m_wwwsToDispose[i].url + ", " + m_wwwsToDispose[i].error);
m_wwwsToDispose[i].Dispose();
m_wwwsToDispose.RemoveAt(i);
i--;
}
}
}
public static WWWDisposer GetDisposer()
{
GameObject gameObject = GameObject.Find("_wwwDisposer");
if(gameObject == null)
{
gameObject = new GameObject("_wwwDisposer");
gameObject.AddComponent<WWWDisposer>();
}
return gameObject.GetComponent<WWWDisposer>();
}
}
This is useful if you want to for example wait a maximum of 5 seconds to retrieve an asset from the server, if the request times out, you can use an embedded low res asset or a cached one.
Awesome, this fixed my Android Unity freezes upon inabilities to connect to the server. Thanks so much @peacefulshade
Answer by rutter · Oct 31, 2013 at 12:28 AM
I don't think you can override the default timeout, but remember that your coroutine can yield on values other than the WWW. You could instead check each frame (or every X seconds) if the WWW isDone.
If the WWW doesn't finish within whatever time limit you track, your coroutine can do something to handle that appropriately.
I ended up using Abacus's code from here to do that, and it seems to work...mostly. This still seems like a fairly messy process.
http://forum.unity3d.com/threads/36065-How-to-stop-the-www-request