2017-07-02 12 views
0

私の関数から文字列値を返したいと思います。しかし、私はそれをどう扱うべきか分からないのですか?私は最終的な1アレイソリューションを試しましたが、うまくいかなかったのです。ここでRetrofit v2のonResponseから値を返すには

は私のコードです:revealCourtPlaceが戻ってきた後に、それはおそらく終了しますので

public String revealCourtPlace(String courtID) 
{ 

    BaseService.getInstance().getUniqueCourt(Session.getToken(),courtID).enqueue(new Callback<JsonObject>() 
    { 
     @Override 
     public void onResponse(Call<JsonObject> call, Response<JsonObject> response) 
     { 

      JsonObject object = response.body(); 
      boolean success = object.get("success").getAsBoolean(); //json objesinde dönen success alanı true ise 
      if (success) 
      { 
       JsonArray resultArray = object.get("data").getAsJsonObject().get("result").getAsJsonArray(); 
       for (int i = 0; i < resultArray.size(); i++) 
       { 
        JsonObject jsonInfoResult = resultArray.get(i).getAsJsonObject(); 
        String courtName=jsonInfoResult.get("name").getAsString(); 
       } 

      } 

     } 

     @Override 
     public void onFailure(Call<JsonObject> call, Throwable t) 
     { 

     } 

    }); 

    //return ? 
} 
+0

'onResponse'は非同期的に呼び出されます。つまり、f rom 'revealCourtPlace'です。 –

+0

あなたは言う、文字列の値を取得する方法はありません? –

+0

あなたのロジックをより反応的にするように構造化する必要があります。非同期イベント/アップデートに応答します。 'RxJava'を見てください(' retrofit'も 'RxJava'をサポートしています) –

答えて

6

onResponseは非同期です。

onResponseのようなものは、その中から返品することはできません。しかし、値を渡すか、Rxのようなもので動作するようにコードを再構成することはできます。

私を説明しましょう。したがって、コールバックを使用して必要な文字列値を渡すこともできます。

public interface RevealCourtPlaceCallbacks { 
    void onSuccess(@NonNull String value); 

    void onError(@NonNull Throwable throwable); 
} 

これらは、ネットワーク通話の価値を受け取りたい方は誰でも実装する必要がある方法です。メソッドはvoidを返す:あなたはrevealCourtPlace

public void revealCourtPlace(String courtID, @Nullable RevealCourtPlaceCallbacks callbacks) 
{ 
    BaseService.getInstance() 
     .getUniqueCourt(Session.getToken(),courtID) 
     .enqueue(new Callback<JsonObject>() { 
    @Override 
    public void onResponse(Call<JsonObject> call, Response<JsonObject> response) 
    { 

     JsonObject object = response.body(); 
     boolean success = object.get("success").getAsBoolean(); //json objesinde dönen success alanı true ise 
     if (success) 
     { 
      JsonArray resultArray = object.get("data").getAsJsonObject().get("result").getAsJsonArray(); 
      for (int i = 0; i < resultArray.size(); i++) 
      { 
       JsonObject jsonInfoResult = resultArray.get(i).getAsJsonObject(); 
       String courtName=jsonInfoResult.get("name").getAsString(); 

       if (callbacks != null) 
        calbacks.onSuccess(courtName); 
      } 

     } 

    } 

    @Override 
    public void onFailure(Call<JsonObject> call, Throwable t) 
    { 
     if (callbacks != null) 
      callbacks.onError(t); 
    } 

    }); 
} 

メソッドに渡すことで、たとえば注目すべき重要なことを、これを使用しています。コールバックを引数として渡します。これらのコールバックは、誰がメソッドを呼び出すか、呼び出し元で実装された匿名クラスとして実装する必要があります。

これにより、文字列courtNameを非同期で受信でき、値を返すことを心配する必要がなくなります。

コードを有効にすることができる別のオプションがあります。これはもう少し仕事であり、パラダイムシフトです。 Rx javaの知識も必要です。これをどうやって行うかの例をここに残しておきます。これを行うにはいくつかの方法があることに注意してください。

最初に、改造インターフェイスを別に定義する必要があります。戻り値の型は現在、観測可能である必要があります。

public interface CourtApiClient { 
    @GET(/*...*/) 
    Single<JsonObject> getUniqueCourt(/*...*/); 
} 

私は本当にあなたのコールの全体のインタフェースの詳細を知らないが、ここで重要な部分は、戻り値の型が今Singleです。これは1つの項目または複数のエラーしか出さないRx観測値です。型もJsonObject以外のものでなければなりませんが、これはコードからどのようなものであるべきかを判断するのは非常に難しいです。とにかく、これも動作します。

は、次のステップは、単にあなたのrevealCourtPlace方法から結果を返すことです:

public Single<JsonObject> revealCourtPlace(String courtID, @Nullable RevealCourtPlaceCallbacks callbacks) 
{ 
    return BaseService.getInstance() 
     .getUniqueCourt(Session.getToken(),courtID); 
} 

ここでの重要な違いは、この方法が今、観察を返し、あなたはいつでもあなたがそれを購読することができるということです。これにより、実際には非同期ですが、フローは同期しているように見えます。

これで、JsonObjectを必要な数の文字列にマップするか、購読者で解析するかの選択ができました。

編集

あなたはあなたの関数を呼び出すことができますどのようにコメントで尋ねたので、ここでは可能性があります:

revealCourtPlace("some court id", new RevealCourtPlaceCallbacks() { 
     @Override 
     public void onSuccess(@NonNull String value) { 
      // here you use the string value 
     } 

     @Override 
     public void onError(@NonNull Throwable throwable) { 
      // here you access the throwable and check what to do 
     } 
    }); 

また、あなたがこれらのコールバックを実装して、呼び出し元のクラスを作ることができますし、単にthisを渡します。

revealCourtPlace("some court id", this); 
+0

返信先をご案内いただきありがとうございます。それはちょうどすごいです。しかし、私の機能をどう呼び出すことができますか? revealCourtName(courtID ,?); –

+0

@YunusHaznedar私は自分の答えを編集しました。それがあなたを助けるかどうかチェックしてください! – Fred

+0

ご指導ご返信ありがとうございます。それは私が間違っていることを見て私を助けるでしょう。再度、感謝します。 –

関連する問題