0

Вопрос заключается в том, как связаться с телефоном Android на сервере, чтобы, если действие осталось, а вызов в Activity не был успешным, повторить транзакцию один раз снова автоматически. Только сейчас я использую AsyncTask Андроида для связи с сервером:Где разместить код Android для связи с сервером по http:

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; 
    } 
} 

Проблема с этим подходом в том, что если у меня нет успешной передачи данных я должен оставаться в одной и той же деятельности. До сих пор я показываю сообщение об ошибке пользователю, и он отвечает за отправку с помощью кнопки снова результатов на сервер. Что я ищу - это некоторая активность, которая остается постоянной в памяти, которая запускается позже в случае, когда передача не была выполнена.

В качестве приложения я использую это для динамической загрузки изображений для путевой точки на карте, если я нажал эту путевую точку. В некоторых случаях может случиться так, что соединение с поставщиком мобильной связи недоступно (горы, лес, далеко от антенны). Затем я хочу покинуть карту Activity и перейти к подробному представлению этой путевой точки. В случае успеха я помещал изображение в свои классы моделей и делал сериализацию. Если пользователь снова нажимает на ту же путевую точку, изображение снова не загружается. В случае отсутствия успеха я не хочу ждать, когда пользователь нажимает на путевую точку, чтобы получить изображение. На самом деле мне нужна фоновая задача, какая-то очередь, в которую загруженные снимки путевых точек, которые уже были посещены, не могут быть загружены до тех пор, пока часть связи не вернет положительный результат, и изображение может быть записано в модель. В следующий раз, когда пользователь нажимает «Путевую точку», изображение будет присутствовать.

Есть ли какие-либо передовые методы для реализации такого кода? Есть ли какой-нибудь пример? Есть ли лучший способ сделать это?

ответ

0

Да, вам нужно реализовать Intent Service это требование

По данным сайта разработчиков

Класс IntentService обеспечивает простую структуру для выполнения операции на одном фоновом потоке.

Для получения полной информации и рабочего исходного кода, Переход через Android Docs

0

Благодаря ответ Давида.

Я только что прочитал после того, как предложение учебника по

[1] http://code.tutsplus.com/tutorials/android-fundamentals-intentservice-basics--mobile-6183

После моих тестов я предпочитаемая Службу (не 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(); 
    } 

} 

Дальше я добавил a ResponseReceiver:

public class ResponseReceiver extends BroadcastReceiver { 
    public static final String ACTION_RESP = "MESSAGE_PROCESSED"; 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     //work in progress... 
    } 
} 

и в деятельности, где я хочу быть в курсе событий:

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 (...) из разных видов деятельности. Конструктор вызывается только один раз. ==> У меня есть только сервис для всех видов деятельности (именно то, что мне нужно).

То, что я до сих пор не получаю: - Возврат данных к деятельности. Что есть, если в данный момент активность не показана?

+0

Храните данные в некоторых переменных, и когда ваша деятельность будет восстановлена, то есть внутри метода onResume вашей деятельности. Установите эти данные в представления. –