2017-09-28 7 views
1

사용하여 요청을 취소하는 방법. 문제는입니다. CHAR을 삽입 할 때마다 새로운 요청을하지만 동시에 이전 요청을 취소해야합니다! 예 : 뉴욕 = 13 건의 요청 그래서 나는 Call의 단일 인스턴스를 사용하여 요청되었지만 성공하지 못한 것을 취소하려고합니다. 이것이 내가 한 일이다!내가 주소를 입력하여 몇 가지 예측을받을 수 <code>Google Places AutoComplete</code>을 사용하여, <strong>OKHTTP</strong>와 <strong>MANAGER</strong> 어떤 요청을 할 수 있어야합니다 OKHTTP

Address.addTextChangedListener(new TextWatcher() { 
     @Override 
     public void beforeTextChanged(CharSequence s, int start, int count, int after) { 

      if(Address.getText().toString().length() > 3){ 
       _Address = Address.getText().toString(); 
       if(call != null){ 
        call.cancel(); 
       } 
       Request request = new Request.Builder() 
         .url(getPlaceAutoCompleteUrl(_Address)) 
         .addHeader("content-type", "application/json") 
         .addHeader("User-Agent", "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; google_sdk Build/MR1) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30") 
         .build(); 
       call = client.newCall(request); 


       call.enqueue(new Callback() { 
        public void onResponse(Call call, final Response response) throws IOException { 
         final String result = response.body().string(); 
         runOnUiThread(new Runnable() { 
          @Override 
          public void run() { 
           Log.d("Response",result); 
           PlacePredictions place = null; 
           try { 
            place = LoganSquare.parse(result,PlacePredictions.class); 
           } catch (IOException e) { 
            e.printStackTrace(); 
           } 
           if(autoCompleteAdapter == null){ 
            autoCompleteAdapter = new AutoCompleteAdapter(CustomPlaces.this); 
            recyclerView.setAdapter(autoCompleteAdapter); 
            autoCompleteAdapter.Add(place.getPlaces()); 
           }else { 
            autoCompleteAdapter.Clear(); 
            autoCompleteAdapter.Add(place.getPlaces()); 
            autoCompleteAdapter.notifyDataSetChanged(); 
           } 
          } 
         }); 
        } 
        public void onFailure(Call call, IOException e) { 
         //fail(); 
        } 
       }); 
      }else { 
       if(autoCompleteAdapter != null){ 
        autoCompleteAdapter.Clear(); 
       } 
      } 
     } 

은 내가 call 객체가 null의 경우 확인 요청을 취소하지만 여전히오고 계속! 다음에 대한

+0

사용자가 입력 한 각 문자에 대한 요청을 만드는 이유는 무엇입니까? 일부 시간 초과 (예 : 1 초)를 추가하고 사용자가 1 초 동안 아무 것도 입력하지 않은 경우에만 요청을 보냅니다. 예제 코드를 제공 할 수 있습니다. – babay

+0

제공하는 것이 좋을 것입니다. 감사합니다! –

답변

2

무엇 :

  //Set tags for your requests when you build them: 
      Request request = new Request.Builder(). 
      url(url).tag("requestKey").build(); 

      //When you want to cancel: 
      //A) go through the queued calls and cancel if the tag matches: 
      for (Call call : mHttpClient.dispatcher().queuedCalls()) { 
       if (call.request().tag().equals("requestKey")) 
        call.cancel(); 
      } 

      //B) go through the running calls and cancel if the tag matches: 
      for (Call call : mHttpClient.dispatcher().runningCalls()) { 
       if (call.request().tag().equals("requestKey")) 
        call.cancel(); 
      } 
+0

좋아요, 코드를 그대로두면 요청과 2 개의 "for"라는 태그를 추가해야합니다. 그래서 매번 새로운 숯을 추가 할 때마다 응답을 리턴하지 못하게 할 것입니다. –

+0

먼저 취소해야합니다 (새 것을 취소하지 않으므로) :-) 메소드에 cancelPending을 또한 리팩토링합니다. – TomerBu

+0

나는 시도 할 것이다! 감사! –

1

지연 서버에 요청 (더 나은 느낌으로 조정, 1000 밀리 초) 입력이 시간 초과 변경되지 않은 경우에만 게시 할 수 있습니다. 취소 방법을 추가 할 수 있습니다. GetHintsRequest

... 
    Address.addTextChangedListener(new TextWatcher() { 
     @Override 
     public void afterTextChanged(Editable s) { 
      if (s.length() < 3) { 
       if (autoCompleteAdapter != null) { 
        autoCompleteAdapter.Clear(); 
       } 
       return; 
      } 

      GetHintsRequest request = new GetHintsRequest(s.toString(), new GetHintsRequest.GetHintsCallback() { 
       @Override 
       public boolean isRequestNotChanged(String oldRequest) { 
        return Address.getText().toString().equals(oldRequest); 
       } 

       @Override 
       public void onGotHints(String request, PlacePredictions predictions) { 
        if (autoCompleteAdapter == null) { 
         autoCompleteAdapter = new AutoCompleteAdapter(CustomPlaces.this); 
         recyclerView.setAdapter(autoCompleteAdapter); 
         autoCompleteAdapter.Add(place.getPlaces()); 
        } else { 
         autoCompleteAdapter.Clear(); 
         autoCompleteAdapter.Add(place.getPlaces()); 
         autoCompleteAdapter.notifyDataSetChanged(); 
        } 
       } 
      }); 
      request.postCheck(); 
     } 
    }); 
... 

public class GetHintsRequest { 
    private static final long TIMEOUT_MS = 1000; // timeout 
    private final String requestText; 
    private final GetHintsCallback callback; 
    // android.os.Handler, can be used to post and delayed post to main thread. activity.runOnUiThread uses it 
    private final Handler handler = new Handler(Looper.getMainLooper()); 

    public GetHintsRequest(String requestText, GetHintsCallback callback) { 
     this.requestText = requestText; 
     this.callback = callback; 
    } 

    public void postCheck() { 
     handler.postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       if (callback.isRequestNotChanged(requestText)){ 
        execute(); 
       } 
      } 
     }, TIMEOUT_MS); 
    } 


    public void execute() { 
     Request request = new Request.Builder() 
       .url(getPlaceAutoCompleteUrl(_Address)) 
       .addHeader("content-type", "application/json") 
       .addHeader("User-Agent", "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; google_sdk Build/MR1) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30") 
       .build(); 
     call = client.newCall(request); 

     call.enqueue(new Callback() { 
      public void onResponse(Call call, final Response response) throws IOException { 
       final String result = response.body().string(); 
       handler.post(new Runnable() { 
        @Override 
        public void run() { 
         Log.d("Response", result); 
         PlacePredictions place = null; 
         if (callback.isRequestNotChanged(requestText)) { 
          try { 
           place = LoganSquare.parse(result, PlacePredictions.class); 
          } catch (IOException e) { 
           e.printStackTrace(); 
           return; 
          } 
          callback.onGotHints(requestText, place); 
         } 
        } 
       }); 
      } 

      public void onFailure(Call call, IOException e) { 
       //fail(); 
      } 
     }); 
    } 

    public interface GetHintsCallback { 
     boolean isRequestNotChanged(String oldRequest); 

     void onGotHints(String request, PlacePredictions predictions); 
    } 

} 
+0

감사합니다. 나는 시도 할 것이다. 가장 큰 문제는 내가 뭔가를 할 때마다 요청을 취소하는 것입니다. –