1

私は1つの実装で悩んでいます。私はサードパーティのSDK(ライブラリ)を統合し、そのAPIを呼び出すAndroidアプリケーションを開発しています。 SDKの関数呼び出しは、実際には応答(成功または失敗)を返す非同期呼び出し(ライブラリによって呼び出されるWebAPI呼び出し)です。Android:すべての非同期呼び出しが完了したときに通知されます

ここでは、コードで状況を説明しようとしています。

for (................) { 
    AsyncAPICall (SuccessListener { 
     onSuccess() { 
      for (................) { 
       AsyncAPICall (SuccessListener { 
        onSuccess() { 
         for (................) { 
          AsyncAPICall (SuccessListener, ErrorListener); 
         } 
        } 
       }, ErrorListener); 
      } 
     } 
    }, ErrorListener); 
} 

通知またはコールバックが必要な場合や、すべての非同期呼び出しが完了したことが通知されたい場合。非同期呼び出しは別のスレッドで実行され、forループによって多くの呼び出しが同時に行われます。

すべての非同期呼び出しが応答を受け取った後、手動で何かする必要があることを通知するメカニズムはありますか?

助けが必要ですか?

答えて

0

@Khushbu Shah、私は私の答えを更新しました、それは少し変更:)(それはかなり長いです)。必ずそれが働いて、私は一人で作業例をスタンドを作成し、テストするには、このAPIを使用するようにするに
https://jsonplaceholder.typicode.com/posts/1

private final Retrofit retrofit = new Retrofit.Builder() 
      .baseUrl("https://jsonplaceholder.typicode.com/posts/") 
      .addConverterFactory(GsonConverterFactory.create()) 
      .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 
      .build(); 

    private final RestPostsService restPostsService = retrofit.create(RestPostsService.class); 

    private Observable<Posts> getPostById(int id) { 
     return restPostsService.getPostsById(id); 
    } 

ソリューション1使用以前の結果、配列中に複数のタスクを呼び出しますタスクは、常に次のタスク

getPostById(1) 
       .concatMap(posts1 -> { 
        //get post 1 success 
        return getPostById(posts1.getId() + 1); 
       }) 
       .concatMap(posts2 -> { 
        //get post 2 success 
        return getPostById(posts2.getId() + 1); 
       }) 
       .concatMap(posts3 -> { 
        //get post 3success 
        return getPostById(posts3.getId() + 1); 
       }) 
       .subscribeOn(Schedulers.io()) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .subscribe(finalPosts -> { 
        //get post 4 success 
        Toast.makeText(this, "Final result: " + finalPosts.getId() + " - " + finalPosts.getTitle(), 
          Toast.LENGTH_LONG).show(); 
       }); 

の入力でありますSolution2複数のタスクを連続して呼び出す場合は、前のタスクの結果はすべて最終タスクの入力です(例:アバターイメージをアップロードしてイメージをカバーし、APIを呼び出してイメージURLを持つ新しいユーザーを作成した場合)

Observable 
       .zip(getPostById(1), getPostById(2), getPostById(3), (posts1, posts2, posts3) -> { 
        //this method defines how to zip all separate results into one 
        return posts1.getId() + posts2.getId() + posts3.getId(); 
       }) 
       .flatMap(finalPostId -> { 
        //after get all first three posts, get the final posts, 
        // the final posts-id is sum of these posts-id 
        return getPostById(finalPostId); 
       }) 
       .subscribeOn(Schedulers.io()) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .subscribe(finalPosts -> { 
        Toast.makeText(this, "Final posts: " + finalPosts.getId() + " - " + finalPosts.getTitle(), 
          Toast.LENGTH_SHORT).show(); 
       }); 

AndroidManifest

<uses-permission android:name="android.permission.INTERNET"/> 

ルートbuild.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules. 

buildscript { 
    repositories { 
     jcenter() 
    } 
    dependencies { 
     classpath 'com.android.tools.build:gradle:2.3.3' 
     classpath 'me.tatarka:gradle-retrolambda:3.2.0' 
     classpath 'me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2' 

     // NOTE: Do not place your application dependencies here; they belong 
     // in the individual module build.gradle files 
    } 

    // Exclude the version that the android plugin depends on. 
    configurations.classpath.exclude group: 'com.android.tools.external.lombok' 
} 

allprojects { 
    repositories { 
     jcenter() 
    } 
} 

task clean(type: Delete) { 
    delete rootProject.buildDir 
} 

APP/build.gradle

apply plugin: 'me.tatarka.retrolambda' 
apply plugin: 'com.android.application' 

android { 
    compileSdkVersion 26 
    buildToolsVersion "26.0.1" 
    defaultConfig { 
     applicationId "app.com.rxretrofit" 
     minSdkVersion 15 
     targetSdkVersion 26 
     versionCode 1 
     versionName "1.0" 
     testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 
    } 
    buildTypes { 
     release { 
      minifyEnabled false 
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
     } 
    } 

    compileOptions { 
     sourceCompatibility JavaVersion.VERSION_1_8 
     targetCompatibility JavaVersion.VERSION_1_8 
    } 
} 

dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 
     exclude group: 'com.android.support', module: 'support-annotations' 
    }) 
    compile 'com.android.support:appcompat-v7:26.+' 
    compile 'com.android.support.constraint:constraint-layout:1.0.2' 
    testCompile 'junit:junit:4.12' 

    provided 'org.projectlombok:lombok:1.16.6' 
    compile 'com.squareup.retrofit2:retrofit:2.3.0' 
    compile 'com.squareup.retrofit2:converter-gson:2.3.0' 
    compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0' 
    compile 'io.reactivex:rxandroid:1.2.1' 
} 

モデル

package app.com.rxretrofit; 
import com.google.gson.annotations.SerializedName; 
/** 
* -> Created by Think-Twice-Code-Once on 11/26/2017. 
*/ 
public class Posts { 
    @SerializedName("userId") 
    private int userId; 
    @SerializedName("id") 
    private int id; 
    @SerializedName("title") 
    private String title; 
    @SerializedName("body") 
    private String body; 
    public int getUserId() { 
     return userId; 
    } 
    public void setUserId(int userId) { 
     this.userId = userId; 
    } 
    public int getId() { 
     return id; 
    } 
    public void setId(int id) { 
     this.id = id; 
    } 
    public String getTitle() { 
     return title; 
    } 
    public void setTitle(String title) { 
     this.title = title; 
    } 
    public String getBody() { 
     return body; 
    } 
    public void setBody(String body) { 
     this.body = body; 
    } 
} 

RestPostService.java

package app.com.rxretrofit; 

import retrofit2.http.GET; 
import retrofit2.http.Path; 
import rx.Observable; 

/** 
* -> Created by Think-Twice-Code-Once on 11/26/2017. 
*/ 

public interface RestPostsService { 

    @GET("{id}") 
    Observable<Posts> getPostsById(@Path("id") int id); 
} 

ところで、Rx + Retrofit + Dagger + MVPパターンは素晴らしい組み合わせです。

+1

私はrxjavaがここでうまくいくと思いますが、あなたの例はほとんど意味がなく、予想されるzip()observeOn()とsubscribeOn()は少なくとも –

+2

"Thanks @ @ Twink Code Once"です。最初に私はRxJavaを理解しています。その後、私はこの解決策を試してみましょう。 –

+0

@TimCastelijnsこの回答を与える前にObservable.zip()を見ましたが、この解決策はもっと簡単だと思います。 –

関連する問題