2015-06-12 38 views
3

在我们正在制作的应用程序中,我们希望在应用程序挂起时尝试​​远程用户保存数据。在Unity的编辑器,在Android上,这很简单,只要Unity3D在iOS上的主线程上的WWW调用

WWW www = new WWW(_URL); 
while(!www.isDone) 
{ 
    Thread.Sleep(100); 
} 
Debug.Log(www.text); 

(全样本:https://github.com/SixMinute/iOSWWWGet

但在iOS上,www.isDone而我们阻止从未值为true,那么整个事情只是挂起。

这是一个错误,或通过设计?然后,如果是设计,那么这样做的正确方法是什么,因为如果我们把它放在StartCoroutine之后,它在主线程中不正确,并且在暂停时,发生什么事情会在应用程序恢复时推送到它(这完全击败了我们正在努力的目的)。

编辑:在与IRC上的一些Unity开发人员交谈后,他们接受这实际上是代码中的错误,了解我需要这个的原因,并且接受需要有一种方法来同步激发WWW请求,或者在iOS的OnApplicationPause(true)流程中调用时启用此功能的其他方式,因为否则(尽管能够轻松地在本地执行),但当时无法启动WWW请求,唯一的选择是将它们排队,直到简历,这是完全不切实际的。

回答

1

在这一刻团结不启动一个新的线程WWW行动,至少在一些平台(iOS,webplayer)。或者如果是这样,它会在主线程上设置WWW.isDone。所以这段代码:

while(!www.isDone) 
    Thread.Sleep(500); 

不起作用。

+0

是的,我添加了来自Unity iOS开发者的响应。虽然在这种情况下这是平台的一个限制,但在挂起流程期间,仍然有一种方法可以从“OnApplicationPause(true)”调用中触发WWW请求。在目前最简单的形式中,你的回答是正确的,我会将其标记为这样,但希望Unity修复该错误/允许在iOS上执行此操作的方法,然后将该方法作为答案添加。 – seaders

-1

入住这对Unity Documentation

使用协程,while循环将被阻止在网络播放器:

void SaveDate() 
{ 
StartCoroutine("SaveWebData"); 
} 

IEnumerator SaveWebData() 
{ 
// Start a download of the given URL 
WWW www = new WWW(_URL); 

// Wait for download to complete 
yield return www; 

// Completed! 
Debug.Log(www.text); 
} 
+1

你能提供一些代码,因为该页面是非常缺乏信息和*正如我所说的*,使用'StartCoroutine'推动任何东西'yield'当应用程序恢复后出现这种情况。我需要在编辑器和Android上的主线程上下载。 – seaders

+0

_ [你的回答是在另一座城堡:何时答案不是答案?](http://meta.stackexchange.com/questions/225370/your-answer-is-in-another-castle-when-is-的回答 - 不的回答)_。考虑编辑您的答案以包含链接指向的文章摘要。 – MickyD

+0

对不起,编辑。现在好多了? – joreldraw

1

以任何你想要的方法开始你的www电话。在更新期间,请检查www.isDone ...如果返回true,则对其执行操作...否则,请通过。

private WWW myRequest = null; 

void Update() 
{ 
    if (myRequest != null) 
    { 
     if (myRequest.isDone) 
     { 
      // process request here 

      myRequest = null;// reset it 
     } 
    } 
} 

如果你想支持发射一个以上的WWW请求一次,把你的WWW请求中的数组列表myRequests =新名单()和遍历那些在更新,而不是和检查每个人的状态。在使用它时,您无法从myRequests中删除,因此请记下临时删除列表。

private List<WWW> myRequests = new List<WWW>() 

void Update() 
{ 
    if (myRequests.Count > 0) 
    { 
     List<WWW> removeList = null; 

     foreach (WWW myRequest in myRequests) 
     { 
      if (myRequest.isDone) 
      { 
       // process request here 

       if (removeList == null) 
       { 
        removeList = new List<WWW>(); 
       } 
       removeList.Add(myRequest); 
      } 
     } 
     if (removeList != null) 
     { 
      foreach (WWW oldReq in removeList) 
      { 
       myRequests.Remove(oldReq); 
      } 
     } 
    } 
}