2017-09-26 14 views
-1

私のアプリで簡単にhttpリクエストを送信するために、ボレーライブラリにリアクティブラッパーを作成しています。ここではクラスがある:サブスクリプションが破棄されたときObservable内で長時間実行されているタスクをキャンセルする

/** 
* Used to send a http GET/POST request. 
*/ 

public class BasicRequest { 
public static final String LOG_TAG = "BasicRequest"; 

public static final int GET_REQUEST = Request.Method.GET; 
public static final int POST_REQUEST = Request.Method.POST; 
private final int mRequestType; 
private final String mServiceLocation; 
private final Map<String, String> mParams; 

/** 
* Keeps track of all the request for this object. Will be helpful when we need to cancel 
* the request when someone disposes the subscription. 
*/ 
private List<StringRequest> mStringRequests = new ArrayList<>(); 

private Context mContext; 

private int mRequestTimeout = BASIC_REQUEST_DEFAULT_TIMEOUT; 

public BasicRequest(Context context, 
        String serviceLocation, 
        int requestType, 
        final Map<String, String> params) { 
    mContext = context; 
    mRequestType = requestType; 
    mServiceLocation = serviceLocation; 
    mParams = params; 
} 

private void fireRequest(final SingleEmitter<String> e) { 

    StringRequest stringRequest; 
    if(mRequestType == GET_REQUEST) { 
     stringRequest = new StringRequest(Request.Method.GET, mServiceLocation, 
       new Response.Listener<String>() { 
        @Override 
        public void onResponse(String response) { 
         e.onSuccess(response); 

        } 
       }, new Response.ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError error) { 
       e.onError(error); 
      } 
     }); 
    } else { 
     stringRequest = new StringRequest(Request.Method.POST, mServiceLocation, 
       new Response.Listener<String>() { 
        @Override 
        public void onResponse(String response) { 
         e.onSuccess(response); 
        } 
       }, new Response.ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError error) { 
       e.onError(error); 
      } 
     }) { 
      @Override 
      protected Map<String, String> getParams() throws AuthFailureError { 
       return mParams; 
      } 

     }; 
    } 
    mStringRequests.add(stringRequest); 
    stringRequest.setRetryPolicy(new DefaultRetryPolicy(
      mRequestTimeout, 
      ConnectionUtils.BASIC_REQUEST_DEFAULT_RETRIES, 
      DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); 
    VolleyInstance.getInstance(mContext).addToRequestQueue(stringRequest); 
} 


/** 
* Returns a Single observable for results. Queues the request on Subscription. Must be 
* called only once during the lifetime of object. Calling multiple times will return null. 
* Expect to get VolleyException in case of error. 
* @return Single observable for String results. If it's is used for second time, it will 
* return null. 
*/ 
@Nullable 
public Single<String> get() { 

    return Single.create(new SingleOnSubscribe<String>() { 
     @Override 
     public void subscribe(@NonNull SingleEmitter<String> e) throws Exception { 
      fireRequest(e); 
     } 
    }).doOnDispose(new Action() { 
     @Override 
     public void run() throws Exception { 
      for (StringRequest stringRequest: mStringRequests) { 
       stringRequest.cancel(); 
      } 
     } 
    }); 

} 

/** 
* Set the request timeout for this request. 
* @param requestTimeout time in milliseconds. 
*/ 
public void setRequestTimeout(int requestTimeout) { 
    mRequestTimeout = requestTimeout; 
} 

今の問題は誰かがサブスクリプションを配置する際に、すべてのサブスクリプションに対応するすべての要求が停止されますです。サブスクリプションが却下された要求を止めることができる方法はありますか?

一度だけ達成することは、1つのサブスクリプションしか維持できないことを知っています。誰かが再び呼び出すと、キャッシュされたオブザーバーが返されます。サブスクリプションの処分に基づいてhttpリクエストを処理する良い方法はありますか?あなたはfireRequest外にそれを管理する必要はありません

答えて

1

SingleEmitterは、まさにそのためのsetCancellable方法がありますがキャンセルを行い、そしてRxJavaは、誰かが観測を配置するとき、それを呼び出すことを確認します。

fireRequest()方法で追加、およびdoOnDisposeを削除します。

e.setCancellable(()-> stringRequest.cancel()); 
+0

うわー、それを知っているdin't。どうもありがとう! :) –

関連する問題