final ArrayList<String> users = new ArrayList<>(); for ( VKApiDialog msg : list) { final String[] result = new String[1]; final int id=msg.message.user_id; VKRequest request1 = VKApi.users().get(VKParameters.from(VKApiConst.USER_IDS,String.valueOf(msg.message.user_id),VKApiConst.FIELDS, "first_name, last_name")); request1.executeWithListener(new VKRequest.VKRequestListener() { @Override public void onComplete(VKResponse response) { super.onComplete(response); user = ((VKList) response.parsedModel); result[0] =user.getById(id).toString(); } }); users.add(result[0]); } 

after exiting onComplete variable becomes null

if users.add(result[0]) called inside, then when I call onComplete from outside, after users.size() I get 0.

`

  for ( VKApiDialog msg : list) { final String[] result = new String[1]; final int id=msg.message.user_id; VKRequest request1 = VKApi.users().get(VKParameters.from(VKApiConst.USER_IDS,String.valueOf(msg.message.user_id),VKApiConst.FIELDS, "first_name, last_name")); request1.executeWithListener(new VKRequest.VKRequestListener() { @Override public void onComplete(VKResponse response) { super.onComplete(response); user= ((VKList) response.parsedModel); result[0] =user.getById(id).toString(); users.add(result[0]); } }); System.out.println(users.size());` 

Result:

04-12 13:50:00.792 11984-11984/com.example.belzik.messagefromvk I/System.out: 0 04-12 13:50:00.793 11984-11984/com.example.belzik.messagefromvk I/System.out: 0 04-12 13:50:00.793 11984-11984/com.example.belzik.messagefromvk I/System.out: 0 04-12 13:50:00.793 11984-11984/com.example.belzik.messagefromvk I/System.out: 0

  • You will see under debugging that users.add (result [0]) is executed first; or result [0] = user.getById (id) .toString (). I think you will immediately understand the problem - Android Android
  • Most likely VKRequestListener is working asynchronously. In the row users.add(result[0]); you cannot expect result[0] already contain a value. Transfer users.add(result[0]); in onComplete() . - Nofate
  • Tried it, from outside, onComplete called after this users.getSize() , received 0 - kalugin1912
  • @ kalugin1912, are you sure you called users.getSize() after VKRequestListener worked? - Nofate
  • yes, look I added an edit to users.size() - kalugin1912

1 answer 1

If I understand everything correctly, VKRequestListener working asynchronously and you want to wait for it to run for all msg . To do this, you need to independently implement synchronization between the main thread and asynchronous callbacks. You can use CountDownLatch . It works like this:

  • You create something like a counter with an initial value equal to the number of expected events.
  • The main thread waits for the counter to reach zero before continuing.
  • In each asynchronous event listener, in case of success and in case of an error, we reduce the counter by one.

It looks like this:

 final List<String> users = Collections.synchronizedList(new ArrayList<>()); final CountDownLatch latch = new CountDownLatch(list.size()); // наш счетчик for ( VKApiDialog msg : list) { final int id=msg.message.user_id; VKRequest request1 = VKApi.users().get(VKParameters.from(VKApiConst.USER_IDS,String.valueOf(msg.message.user_id),VKApiConst.FIELDS, "first_name, last_name")); request1.executeWithListener(new VKRequest.VKRequestListener() { @Override public void onComplete(VKResponse response) { super.onComplete(response); user = ((VKList) response.parsedModel); users.add(user.getById(id).toString()); latch.countDown(); // уменьшаем при успехе } @Override public void onError(VKError error) { latch.countDown(); // при неудаче тоже уменьшаем } }); } latch.await(); // основной поток будет ждать здесь // тут уже можно вызвать users.getSize() 

Examples of application CountDownLatch in Android is in the official documentation .

  • I still get 0 - kalugin1912
  • output latch.getCount() , did it exactly reach zero? - Nofate
  • no, I/System.out: 10 - kalugin1912
  • ArrayList is not thread safe. It is necessary (if necessary) to use Collections.synchronizedList. And all the code must be executed in a separate thread, otherwise latch will hang up the main thread and will be ANR. - Yura Ivanov
  • @YuraIvanov, thanks for noticing. Fixed - Nofate