2

2レベルのネストされたrecyclerViewを実装していて、両方のリサイクラビューがretrofitを使用してAPI呼び出しを行います。これは、同期要求を行う方法であって、更新 - 非同期要求内で同期要求を行うにはどうすればいいですか

public void loadSectionStories(String sessionKey, CuratedSection section) { 
    Call<JsonArray> subCall; 
    subCall = TravelersApi.endpoint().getCuratedSectionTopics(sessionKey, section.id); 

    try { 
     Response<JsonArray> response = subCall.execute(); 
     if(response.code() != 200) { 
      Toast.makeText(getApplicationContext(), "Cannot load page as of the moment.", Toast.LENGTH_SHORT).show(); 
      return; 
     } 
     JsonArray rawStories = response.body(); 
     if(rawStories.size() == 0) { 
      //TODO: show placeholder 
      return; 
     } 
     ArrayList<CuratedSectionItem> stories = new ArrayList<>(); 
     for(int i = 0; i < rawStories.size(); i++) { 
      JsonObject jStories = rawStories.get(i).getAsJsonObject(); 
      JSONObject temp = new JSONObject(jStories.toString()); 
      JsonObject author = jStories.get("author").getAsJsonObject(); 
      CuratedSectionItem story = new CuratedSectionItem(); 
      story.title = jStories.get("title").getAsString(); 
      story.avatar = author.get("profile_photo").getAsString(); 
      story.displayPhoto = temp.getString("primary_photo"); 
      story.username = author.get("username").getAsString(); 
      story.description = jStories.get("content").getAsString(); 
      story.topicId = jStories.get("id").getAsString(); 
      story.postId = jStories.get("first_post_id").getAsString(); 
      story.hasReacted = false; 
      story.upvotes = jStories.get("stats").getAsJsonObject().get("upvotes").getAsInt(); 
      stories.add(story); 
     } 
     section.stories = stories; 
    } catch (IOException e) { 
     Log.d("ERROR!", e.toString()); 
     e.printStackTrace(); 
    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 
} 

これは、非同期要求を行い、また、スレッド内でloadSectionStoriesを呼び出すメソッドです:

public void loadCuratedSections(final int start, final int limit) { 
    SharedPreferences prefs = getSharedPreferences("user_session", MODE_PRIVATE); 
    final String sessionKey = prefs.getString("session_key", null); 

    Call<JsonArray> call; 
    call = TravelersApi.endpoint().getCuratedSections(sessionKey); 

    call.enqueue(new Callback<JsonArray>() { 
     @Override 
     public void onResponse(Call<JsonArray> call, Response<JsonArray> response) { 
      if(response.code() != 200) { 
       Toast.makeText(getApplicationContext(), "Cannot load page as of the moment.", Toast.LENGTH_SHORT).show(); 
       return; 
      } 
      JsonArray rawSections = response.body(); 
      if(rawSections.size() == 0) { 
       return; 
      } 
      for (int i = start; i < limit; i++) { 
       JsonObject jSection = rawSections.get(i).getAsJsonObject(); 
       final CuratedSection section = new CuratedSection(); 
       section.id = jSection.get("id").getAsString(); 
       section.header = jSection.get("section_header").getAsString(); 
       section.isShown = jSection.get("is_shown").getAsBoolean(); 

       Thread thread = new Thread(new Runnable() { 
        @Override 
        public void run() { 
         loadSectionStories(sessionKey, section); 
        } 
       }); 
       thread.start(); 
       curatedSections.add(section); 
      } 

     } 

     @Override 
     public void onFailure(Call<JsonArray> call, Throwable t) { 
      Log.d("ERROR!", t.toString()); 
      t.printStackTrace(); 
     } 
    }); 
} 

すべてがそのsection.stories事実を除いて正常に動作していますnullを返します。この文はsection.stories = storiesの中にloadSectionStoriesのために私には意味をなさない。

+0

でリクエストを実行します。 –

+0

@TentenPonceこれは私が元々行ったことですが、私は 'NetworkOnMainThreadException'を取得しました。 – Bargain23

答えて

0

同期要求が完了する前(新しいスレッドで実行中)にsection.storiesを使用している場合、現在発生しているnullが返されます。

のでどちらかあなたがあなたの最初の非同期要求が完了した後、それを使用したい場合は、

を新しいスレッドの流れを削除する必要があります。また、あなたの物語が更新されたとき、あなたのリサイクルビューをリロードする必要があります。

なぜ新しいスレッドで同期リクエスト(loadSectionStories)を実行していますか?非同期リクエストと似ていませんか?

0
Retrofit asyncRetrofit = new Retrofit.Builder() 
        .baseUrl(URLS.MAIN_SERVER_URL) 
        // below line create thread for syncrouns request 
        .callbackExecutor(Executors.newSingleThreadExecutor()) 
        .addConverterFactory(GsonConverterFactory.create()) 
        .client(httpClient.build()) 
        .build(); 

これは、スレッドを削除して、もう一度試して、スレッド外)(loadSectionStoriesを呼び出すようにしてくださいasyncronous

関連する問題