2016-10-31 1 views
0

私はオブジェクトの3つのグループが同じレルムデータベースにあります。各グループはタグと他の情報のセットです。各タグについて、IDを受け取るためにネットワークに要求する必要があります。クエリはグループごとに異なります(URLの変更と応答)。遅延によるネットワーク要求のグループ化

各グループの要求を並行して行う必要があり、毎分20クエリを超えることはありません。アクティビティが破壊されても、プログラムは動作するはずです。私はIntentServieをやったが、わからない次のステップは何か。遅れて並列クエリを正しく行うにはどうすればよいですか? IntentServiceを使用することは可能ですか?

問題をよりよく理解するために示された「for」のサイクル。また、すべてのレスポンスを1つのデータベースに書き込む必要があります。そのため、すべてのストリームでアクセスできる必要があります。

public class SubscribersGathering extends IntentService { 

private RealmResults<HashtagObject> hashtags; 
private RealmResults<SearchtagObject> searchtags; 
private RealmResults<NametagObject> nametags; 

public SubscribersGathering() { 
    super("SubscribersGathering"); 
} 

@Override 
protected void onHandleIntent(Intent intent) { 
    Realm realmForThisThread = Realm.getDefaultInstance(); 
    this.hashtags = realmForThisThread.where(HashtagObject.class).findAll(); 
    this.searchtags = realmForThisThread.where(SearchtagObject.class).findAll(); 
    this.nametags = realmForThisThread.where(NametagObject.class).findAll(); 
    realmForThisThread.close(); 

    for(int i=0;i<hashtags.size();i++){ 
     getHashtagTag(hashtags.get(i).getHashtag()); 
    } 
    for(int i=0;i< searchtags.size();i++){ 
     getSearchTags(searchtags.get(i).getId()); 
    } 
    etc  
} 

private void getHashtagTag(final String tagName){ 

      HttpURLConnection urlConnection = null; 
      try { 
       URL url = new URL(“URL_1”); 
       urlConnection = (HttpURLConnection) url 
         .openConnection(); 
       urlConnection.setRequestMethod("GET"); 
       urlConnection.setDoInput(true); 
       urlConnection.connect(); 
       String response = Tools.streamToString(urlConnection 
         .getInputStream()); 
       JSONObject jsonObj = (JSONObject) new JSONTokener(response) 
         .nextValue(); 
       for(int i=0;i<jsonObj.getJSONArray("data").length();i++) { 
        JSONObject json = (JSONObject)  jsonObj.getJSONArray("data").get(i); 
        Log.d(tagName, json.getJSONObject("user").getString("id")); 
       } 
      }catch(Exception exc){ 
       exc.printStackTrace(); 
      }finally { 
       if(urlConnection!=null){ 
        try{ 
         urlConnection.disconnect(); 
        }catch(Exception e){ 
         e.printStackTrace(); 
        } 
       } 
      } 
} 

    private void getSearchTags (final String tagName){ 

    } 

    etc 

}

答えて

1

あなたは、ネットワーク運用の並走を実行するための多くのオプションを持っています。それはあなたが選ぶべきものです。基本的に、私はあなたにこれらのいずれかを示唆することができます。

  1. ExecutorService

    に基づくソリューションは、ランナブルにあなたのタスクを分割し、ExecutorServiceのを使用してそれらを実行します。コードは次のようになります。

    public void onHandleIntent(Intent intent) { 
         Runnable hashtagsTask = new Runnable() { 
          @Override 
          public void run() { 
           for (int i = 0; i < hashtags.size(); i++) { 
            getHashtag(i);// do something, fetch hashtags, etc 
           } 
          }  
         }; 
         Runnable searchtagsTask = new Runnable() { 
          @Override 
          public void run() { 
           // do something 
          } 
         }; 
    
    
         ExecutorService pool = Executors.newFixedThreadPool(3); 
         pool.execute(hashtagsTask); 
         pool.execute(searchtagsTask); 
         // etc 
    
         pool.awaitTermination(); 
    } 
    
  2. をいくつかIntentServicesにあなたのタスクを分割します。したがって、すべてのサービスが独自のデータを取得します。個人的に私はそれが良い解決策だとは思わないが、場合によっては柔軟性があるかもしれない。

  3. RxJavaとそのObservable#zipメソッドを使用します。ここで重要な考え方は、独自のスレッドに各観測可能に加入するようになります。

    public void onHandleIntent(Intent intent) { 
         Observable.zip(
          getHashtags().subscribeOn(Schedulers.newThread()), 
          getSearchtags().subscribeOn(Schedulers.newThread()), 
          new Func2<List<String>, List<String>, Void>() { 
           @Override 
           public Void call(List<String> hashtags, List<String> searchtags) { 
             // do something with your data 
             return null; 
           } 
          } 
        ) 
         .subscribe(); 
    } 
    
    private Observable<List<String>> getHashtags() { 
         return Observable.defer(new Func0<Observable<List<String>>>() { 
           @Override 
           public Observable<List<String>> call() { 
            // fetch your data 
            return null; 
           } 
         }; 
    } 
    
+0

アンドレイ、3例をありがとうございました。理解にはいいですね!私にとっては第一の変種がより好ましい。しかし、IntentServiceスレッドで新しいスレッドを開始すると、問題があるのでしょうか? 3番目の変種は良いかもしれません。私はrxjavaを使わないので知らない。どのような異形を選ぶのですか? – Delphian

+0

@Delphianいいえ、問題はありません。 "pool.awaitTermination();"という行に注目してください。 IntentServiceは、すべてのスレッドが実行を完了するまで待機します。個人的には、RxJavaは強力なライブラリなので、第3のオプションを選択します。データを取り込むのに必要な遅延を簡単に作成できます(遅延演算子を参照)。それを使って遊んでみて、あなたが探しているものがあれば見てみましょう。 RxJavaは、十分な経験がなければ苦痛かもしれません。 –

+0

Andrei、ありがとう! – Delphian

関連する問題