【问题标题】:Android: Queue a post until there is a connectionAndroid:排队发帖直到有连接
【发布时间】:2012-12-05 12:21:51
【问题描述】:

您好,这是一个非常简单的问题,但我怀疑这是一个复杂的答案:

这就是所谓的“矿井场景”

让我解释一下:想象一个简单的场景,您必须制作一个可以 httppost 到网页的应用程序,即使在没有信号的矿井下也是如此。

即如果没有连接,我如何尝试/排队提交事件 (HTTPPOST),然后定期轮询队列(测试是否存在连接)直到事件可以触发。

PS:请注意:请这是关于“如何”而不是关于“错误”的对话,回复:同步性或重复记录或覆盖来自 2 个用户的数据等。

伪代码:

try{
   MyHttpFileUploader myupload = new MyHttpFileUploader();
   myupload.Start();
}
catch (InternetDownException ex){ //<-- how do I "throw" this in the start method gracefully?
   GlobalQueue.Add(myupload); //<-- how do i set a timer properly that can action this queue (.Start() method) and post messages "when complete" to toast on the main ui thread but otherwise not block the ui whatsoever
}

【问题讨论】:

  • 愚蠢的问题,但您显然听说过线程(?)。产生一个线程来处理这个问题有什么问题(如果应用程序可能在完成之前关闭,那么您应该存储状态并根据存储的状态在应用程序启动时恢复)。另外 - “我如何优雅地在 start 方法中“抛出”它是什么意思?......你已经抓住了它......所以要么处理异常(通过启动线程)或重新抛出它以后再抓)
  • http 帖子已经是一个异步事件。这不是 UI 调试。这是一个很好的帖子民意调查,论坛中的示例中缺少很多。如果没有互联网连接,帖子是否会失败,这不需要失败,而是在“x”时间后重试并重复冲洗直到成功。工作流程正是电子邮件用于其发件箱的工作流程。文本用于发送。从服务器重复冲洗直到确定。我不介意它是否只在应用程序在 UI 线程中处于活动状态时冲洗/重复,或者无论用户交互如何,它是否都会在后台永久轮询。
  • 在这方面,它与保存的实例状态或用户应用程序在发起帖子后的交互没有任何关系。
  • 我已经使线程完全按照您所说的进行 - 联系表单存储通过邮件服务器轮询发送的失败尝试,直到邮件服务器重新联机 - 您的情况是典型的长时间运行的线程情况。帖子是否是异步的,除非它是异步帖子的结尾,如果您需要进一步的行为,您必须提供回退。我相信一旦帖子失败,您应该使用线程。
  • 好的,但是 a) 它不是一个邮件服务器,它是一个发送到网络服务器的 http 帖子 b) 如果你愿意分享你的一些代码,我很乐意借用它 - 小心提交一个答案?和 c) 线程不是真正除了整理 OP 之外的 ui 线程之外的点。需要的是一个重试直到完成的队列(即,根据定义不在 ui 线程中)

标签: java android sdk http-post internet-connection


【解决方案1】:

这是一个粗略的(因为我现在主要用 c# 编写代码,它与问题无关)半伪代码,主要是 sun 文档 sn-ps(线程)

创建一个类,该类可以访问扩展 Thread 的异步 post 方法中所需的任何变量,即

 class WorkerThread extends Thread {
     int someDataYouNeed;
     MyHttpFileUploader maybeAClassYouNeedToCommunicateWithAtEnd;
     boolean hasNotFinishedTask = true;
     WorkerThread(int someDataYouNeed, MyHttpFileUploader callBackClass) {
         this.someDataYouNeed = someDataYouNeed;
         this.maybeAClassYouNeedToCommunicateWithAtEnd = callBackClass;
     }

     public void run() {

         while(hasNotFinishedTask){
         //do your work in here 
         //Try contact network endpoint
         try{
             //do a network call and if it doesnt except
             hasNotFinishedWork = false
             //now callback to the class firing a method maybe (I just made one up)
             maybeAClassYouNeedToCommunicateWithAtEnd.Close();
         }catch(TheException ex){ //do nothing or log }
         if(hasNotFinishedTask){
              Thread.Sleep(60000);//retry every minute
            }
         }
     }
 }

//当你的异步任务失败时实例化线程......

 WorkerThread worker = new WorkerThread(42, this);
 worker.start();

现在正如我所说 - 我假设您的应用程序正在智能手机上运行并且可以关闭......如果是这种情况并且只要操作系统允许它,您就可以保存状态(当您创建 WorkerThread ) 即文件系统中的 xml 和 WorkerThread 实例化检查文件是否存在并从文件关闭时离开的位置开始。

关于 a) 尽管我的示例是邮件服务器,但它们都是可能不可用的网络端点

更新:

现在我假设它会是纯 java(记住我是 c#,所以不是经常在平台上),但似乎在较新版本的 java 或 for安卓...

查看this blog post for android specific multi-threading 或谷歌搜索Android 多线程以获取平台特定示例

【讨论】:

  • 并在您的“必须是队列”评论中...在 WorkerThread 运行方法中,您可以通过“事物”列表(即您提供给 WorkerThread构造函数,可能是 xml 文件中的内容列表...),当线程全部完成时 - 退出。
  • 我会给你积分 - 简单的 sleep while 循环作为计时器,很好很容易 - 但我会回来并链接我最终做的事情
  • 我很想看看你还有什么其他策略:)
【解决方案2】:

一种方法是使用IntentServiceAlarmManager 来触发尝试发送数据。

这里有更多关于使用 Intents here 的信息,并且 Intent 可以由 AlarmManager 触发

在这个线程AlarmManager not working也有一些代码示例

【讨论】:

  • 感谢 Rod,我真诚地认为这需要成为一个教程 - 一个用于“获取和缓存 http”json/images/content,另一个用于将 json 队列发送回......在“矿井”中正确完成“方式,即使应用程序工作并只是提醒连接已关闭..我正在努力解决这个问题..关于如何使连接独立的http事件的正确教程..考虑到java是一种“错误管理”语言,它的权力令人震惊-那-be 不要为最终用户程序员争吵
  • 同意,我正在考虑做类似的事情。
猜你喜欢
  • 2013-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-28
  • 1970-01-01
相关资源
最近更新 更多