2016-10-03 2 views
0

Я пытаюсь получить некоторые данные из API, но я всегда получаю null в async-задаче. Вот мой AsyncTask:AsyncTask с результатом ArrayList объектов возвращает null в OnPostExecute

private class DownloadTask extends AsyncTask<Bundle, Void, List<Topic>> { 

    @Override 
    protected void onPreExecute() { 
     HomeActivity.mProgressBar.setVisibility(View.VISIBLE); 
     HomeActivity.mProgressBar.setIndeterminate(true); 
    } 

    @Override 
    protected List<Topic> doInBackground(Bundle... params) { 
     return downloadPhotos(params[0]); 
    } 

    @Override 
    protected void onPostExecute(List<Topic> topics) { 
     HomeActivity.mProgressBar.setVisibility(View.INVISIBLE); 
     HomeActivity.mProgressBar.setIndeterminate(false); 

     Log.d("List Size: ", ""+topics); // 0 

     adapter = new TopicListAdapter(activity, topics); 
     RecyclerView.LayoutManager manager = new MyCustomLayoutManager(activity); 
     recyclerView.setLayoutManager(manager); 
     recyclerView.setItemAnimator(new DefaultItemAnimator()); 
     recyclerView.setAdapter(adapter); 
    } 
} 

метод для извлечения данных должны объединить два массива в один массив, потому что я уверен, извлечение данных из двух мест:

private List<Topic> downloadPhotos(Bundle params) { 
    String profileId = activity.getPreferencesManager().getProfileId(); 
    List<Topic> topicsFromMe, topicsFromFriends; 
    topicsFromFriends = setValuesFromFriends(params); 
    topicsFromMe = setValuesFromMe(profileId, params); 
    topicsFromFriends.addAll(topicsFromMe); 
    sortTopics(topicsFromFriends); 
    int k = topicsFromFriends.size(); 
    Log.d("List Size: ", "" + topicsFromFriends); // here also 0 for size 
    if (k > 10) 
     topicsFromFriends.subList(10, k).clear(); 
    return topicsFromFriends; 
} 

А вот один метод, где я устанавливаю значения в список массивов. Странно, что RecyclerView в этом случае заполняется этим массивом, но я не получаю результаты, которые я хочу. Например, я должен сортировать этот список и показывать только 10 записей.

private List<Topic> setValuesFromFriends(final Bundle params) { 
    final List<Topic> topics = new ArrayList<>(); 
    activity.getSimpleFacebook().getFriends(new OnFriendsListener() { 
     @Override 
     public void onComplete(List<Profile> friends) { 
      for (final Profile profile : friends) { 
       activity.getSimpleFacebook().get(profile.getId(), "photos/uploaded", params, 
         new OnActionListener<List<Photo>>() { 
          @Override 
          public void onComplete(List<Photo> photos) { 
           for (final Photo photo : photos) { 
            // Initialize instance of Topic 
            final User user = photo.getFrom(); 
            final Topic topic = new Topic(); 

            topic.setCaption(photo.getName()); 
            topic.setImageId(photo.getId()); 
            topic.setCreatedTime(photo.getCreatedTime()); 
            topic.setPostImage(photo.getSource()); 
            topic.setUserId(user.getId()); 
            topic.setName(user.getName()); 

            final Bundle likeParams = new Bundle(); 
            likeParams.putString("fields", "total_count"); 
            likeParams.putString("limit", "100000"); 

            activity.getSimpleFacebook().get(photo.getId(), "likes", 
              likeParams, new OnActionListener<List<Like>>() { 
               @Override 
               public void onComplete(List<Like> likes) { 
                topic.setNumOfLikes(likes.size()); 
                topics.add(topic); 
               } 

               @Override 
               public void onThinking() { 
                super.onThinking(); 
               } 
              }); 

           } 
          } 
         }); 
      } 
     } 
    }); 
    return topics; 
} 

ответ

1

Вы используете AsyncTask неправильно.

AsyncTask запускает еще одну Thread (thread1), где он выполняет метод, doenloadPhotos. Этот метод вызывает setValuesFromFriends, который создает другой поток (thread2) с помощью метода getFriends. Когда thread2 запущен, остальная часть кода в setValuesFromFriends будет выполнена.

Так вот как это работает:

private List<Topic> setValuesFromFriends(final Bundle params) { 
    final List<Topic> topics = new ArrayList<>(); 
    //launched process on new thread 
    return topics; //this is 0 as topics = new ArrayList<>(); 
} 

topicsFromFriends = 0 Так что теперь. Следовательно, вы получаете выход = 0.

Фактически thread1 запускается до завершения потока2. Поскольку выход потока1 равен 0, в пользовательском интерфейсе ничего не отображается после onPostExecute

Нет необходимости использовать AsyncTask. Вы должны поместить весь необходимый код внутри onCompletenew OnFriendsListener(). Таким образом, информация будет показана правильно. Вы можете запустить индикатор прогресса до setValuesFromFriends, а затем удалить его в onComplete.

Смежные вопросы