Java 在哪里输入Android代码以通过http与服务器通信

Java 在哪里输入Android代码以通过http与服务器通信,java,android,android-asynctask,background-process,server-communication,Java,Android,Android Asynctask,Background Process,Server Communication,问题是如何与Android手机与服务器通信,以便在活动结束且活动中的呼叫未成功时自动再次重复事务。刚才我使用Android的AsyncTask与服务器进行通信: new AsyncTask<String, Void, List<String>>() { @Override protected void onPreExecute( showWaitDialog(); } @Override prote

问题是如何与Android手机与服务器通信,以便在活动结束且活动中的呼叫未成功时自动再次重复事务。刚才我使用Android的AsyncTask与服务器进行通信:

new AsyncTask<String, Void, List<String>>() {

    @Override
    protected void onPreExecute(
       showWaitDialog();        
    }

    @Override
    protected void onPostExecute(List<String> msgList) {
       //here I put the handling after the POST ie. error and success handling
       hideWaitDialog();

       if (msgList.isEmpty() {
          //success handling --> starting an new Activity
       } else {
          errorView.setText (...);
          errorLayout.setVisibility (View.VISIBLE); 
       }
    } 

    @Override
    protected List<String> doInBackground(String... params) {
       List<String> msgs = new ArrayList<String>();
       try{
          //for example submitting an JSONObject
          JSONObject result = HttpUtils.sendHttpPost(
              AppConstants.WEB_URL, jsonObject);
          //error handling on the result
          boolean hasErrors = JsonResult.isOk(result);
          if (hasErrors) {
              // adding errors to msgs list
              String[] errorMessages = JsonResult.getErrorMessages (result,...);           
              fillList (msgs, errorMessages);
              return msgs;
          }
       } catch (CommunicationError er) {
           msgs.add (er...);
       }
       return msgs;
    }
 } 
newasynctask(){
@凌驾
受保护的void onPreExecute(
showWaitDialog();
}
@凌驾
PostExecute上受保护的void(列表msgList){
//在这里,我将处理放在POST之后,即错误和成功处理
hideWaitDialog();
如果(msgList.isEmpty(){
//成功处理-->启动新活动
}否则{
errorView.setText(…);
errorLayout.setVisibility(View.VISIBLE);
}
} 
@凌驾
受保护列表doInBackground(字符串…参数){
List msgs=new ArrayList();
试一试{
//例如,提交一个JSONObject
JSONObject结果=HttpUtils.sendHttpPost(
AppConstants.WEB_URL,jsonObject);
//对结果进行错误处理
布尔hasErrors=JsonResult.isOk(结果);
如果(有错误){
//将错误添加到msgs列表
字符串[]errorMessages=JsonResult.getErrorMessages(结果,…);
填充列表(MSG、错误消息);
返回MSG;
}
}捕获(通信错误){
msgs.add(er…);
}
返回MSG;
}
} 
这种方法的问题是,如果我没有成功传输数据,我必须保持相同的活动。直到现在,我向用户显示一条错误消息,他负责通过按钮再次向服务器提交结果。 我要寻找的是一些在内存中保持持久性的活动,如果没有进行传输,这些活动将在以后运行

作为一个应用案例,如果我按下地图中的某个航路点,我会使用此功能动态上传该航路点的图片。在某些情况下,可能无法连接到移动服务提供商(山区、森林、远离天线)。然后我想离开地图活动并切换到此航路点的详细视图。在成功的情况下,我将图片放入我的模型类并进行序列化。如果用户再次单击同一航路点,则不会再次加载图片。在未成功的情况下,我不想等待用户单击该航路点重新加载尝试图像。事实上,我需要一个后台任务,在通信部分返回肯定结果并将图像写入模型之前,无法检索已访问的航路点图片的某种队列将被加载。下次用户按下航路点时,图片将出现

有什么最佳实践可以实现这样的代码吗? 有什么例子吗?
有更好的方法吗?

是的,您需要为此需求实施
意向服务

根据开发者网站

IntentService类为在单个后台线程上运行操作提供了一个简单的结构


要获得完整的详细信息和可用的源代码,请浏览

,感谢David的回答

我只是在建议之后读了教程

[1]

经过测试后,我更喜欢服务(而不是IntentService)

并创建了一个服务:SubmissionService

public class SubmissionIntentService extends Service {

    private List<PendingMessage> pMsgList = new CopyOnWriteArrayList<PendingMessage>();
    private Handler handler = new Handler();
    private boolean hasAppStopped = false;
    private Runnable runner;


    public SubmissionIntentService() {
      super();
      Log.d (TAG, "Service created...");
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
      PendingMessage pMessage = (PendingMessage) intent.getParcelableExtra(AppConstants.MESSAGE_OBJECT);
      synchronized (pMsgList) {
         pMsgList.add(pMessage);
      }
      if (runner == null) {
         handler.postDelayed(runner = initializeRunnable(), 500);
      }
      return Service.START_NOT_STICKY;
   }

    private void runAsLongAppIsActive (Runnable runner) {
        if (!hasAppStopped) {
           handler.postDelayed (runner, SOME_INTERVAL_CONSTANT); 
        }
    }

    private Runnable initializeRunnable() {
        Runnable result;
        result = new Runnable() {

             @Override
             public void run() {
                if (pMsgList.isEmpty()) {
                   runAsLongAppIsActive (this);
                   return; 
                }

                PendingMessage[] pMArray = null;

                synchronized(pMsgList) {
                    pMArray = pMsgList.toArray (new PendingMessage[pMsgList.size()]);
                } 
                if (pMArray==null || pMArray.length==0) {
                   runAsLongAppIsActive (this);
                   return;
                }
                Log.d (TAG, "Message List size is actually :"+pMArray.length);

                for (PendingMessage pM: pMArray) {
                     try {
                        JSONObject jsonMess = JSONSendMessage.buildOutput (pM);
                        JSONObject result = HttupUtils.sendHttpPost (WEB_URL, jsonMess);

                        boolean hasErrors = JSONResult.isOk (result);
                        if (hasErrors) {
                           //TODO: error handling in case of transmission
                           //don't remove the message from the queue
                           runAsLongAppIsActive(this); 
                           return; 
                        }
                        //remove pending transmission of the queue if success
                        synchronized (pMsgList) {
                           pMsgList.remove (pM);
                        } 
                        //inform over receiver if activity is shown
                        Intent broadcastIntent = new Intent();
                        //put data in intent
                        sendBroadcast (intent);

                        //more important
                        WayPointModel model = ModelInstance.getWayPointModel();
                        model.addToModel (pM, result);
                        model.store();

                     } catch (Exception e) {
                        continue; //try to send other messages
                     }
                }
                runAsLongAppIsActive (this);
             }

           };
        return result;
    }
}

   @Override
   public void onDestroy() {
      hasAppStopped = true;
      handler.removeCallbacks (runner);
      super.onDestroy();
   }

}
在我希望了解事件的活动中:

public class SomeActivity extends Activity {    
  private ResponseReceiver receiver;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    IntentFilter filter = new IntentFilter(ResponseReceiver.ACTION_RESP);
    filter.addCategory(Intent.CATEGORY_DEFAULT);
    receiver = new ResponseReceiver();
    registerReceiver(receiver, filter);
    ...
 }
}

最后,要通过Http发送消息:

Intent msgIntent = new Intent(this, SubmissionIntentService.class);
msgIntent.putExtra(...);
startService(msgIntent);
不要忘记在清单中声明服务:

<service android:name="ch.xxx.app.service.SubmissionIntentService" />

意见: -我从不同的活动调用了方法startService(…),构造函数只调用了一次。 ==>我为所有活动提供了服务实例(正是我所需要的)

我现在才知道的是:
-将数据放回“活动”。如果“活动”此时未显示,该怎么办?

保留数据是一些变量,以及当“活动”恢复时,即在“活动”的onResume方法内。将该数据设置为视图。
<service android:name="ch.xxx.app.service.SubmissionIntentService" />