对网络请求进行延迟分组

时间:2016-10-31 12:39:08

标签: java android multithreading networking

我有三组对象都在同一个Realm数据库中。每个组都是一组标签和其他信息,对于每个标签,我必须向网络请求接收id。每个组的查询都不同(URL更改和响应)。

有必要并行地为每个组发出请求,每分钟不超过20个查询。即使活动被破坏,该计划也应该有效。我做了IntentServie,但下一步我不知道应该做什么。如何正确地进行延迟的并行查询?是否可以使用IntentService?

循环"对于"显示更好地理解问题。此外,所有响应都应写在一个数据库中,这就是所有流都必须可以访问的原因。

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 个答案:

答案 0 :(得分:1)

您有很多选项可以执行并行运行的网络操作。它取决于你选择什么。基本上,我可以建议你其中一个:

  1. 基于ExecutorService

    的解决方案

    将任务拆分为runnables并使用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方法。这里的关键思想是将每个observable订阅到自己的线程:

    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;
                    }
          };
     }