Задача:
Получить имена пользователей
Проблема:
Для начала я добавляю макеты этих диалогов - первая строчка цикла. Потом я отправляю JSONObject через этот emit (все работает!)
Далее, по логике, должен пройти socket.on, но он очень странно работает. Цикл идет только 4 раза, а лог, который я добавлял внутрь этого socket.on выполнялся куда больше кол-во раз и он находил только одного пользователя. То есть работает бешено и не понятно по какой логике. Может это как-то можно синхронизировать?
for( i= contacts.size()-1; i >= 0; i--){
data.add(new DialogInfo("null", contacts.get(i), "null", "null", contacts.get(i)));
for( i= contacts.size()-1; i >= 0; i--){
try {
obj.put("id", contacts.get(i));
socket.emit("info", obj);
} catch (JSONException e) {
e.printStackTrace();
}
socket.on("user_info", new Emitter.Listener() {
@Override
public void call(Object... args) {
userInfo = (JSONObject) args[0];
try {
adapter.editItemByID(userInfo.getString("id"), new DialogInfo(userInfo.getString("nick"),
userInfo.getString("id"), "null", "null", userInfo.getString("id")));
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
}
Надеюсь, вы сможете помочь решить мне эту проблему!
При выполнении команды socket.on каждый раз вешается листенер, который не убирает предыдущий. Т.е. после прохождения N раз по циклу будет висеть N листенеров. И они все одновременно будут вызываться по этому событию.
Как вариант решения проблемы, если предыдущие листенеры по этому ивенту не нужны, можно непосредственно перед socket.on("user_info", new Emitter.Listener(){})
делать socket.off("user_info")
. Этот метод удалит все листенеры по ивенту "user_info"
. Так же можно убирать конкретный листенер, по конкретному ивенту, если использовать не анонимный класс листенера, а вполне определенный объект класса, вынесенный в переменную, следующим образом socket.off("user_info", onUserInfoListener)
Так же, для наблюдения за событиями, которые эмитятся, я настоятельно рекомендую использовать логи самой socket.io, вместо ручных логов в листенерах, следующим образом. Вспомогательный класс:
import android.util.Log;
import java.util.logging.*;
/**
* Make JUL work on Android.
*/
public class AndroidLoggingHandler extends Handler {
public static void reset(Handler rootHandler) {
Logger rootLogger = LogManager.getLogManager().getLogger("");
Handler[] handlers = rootLogger.getHandlers();
for (Handler handler : handlers) {
rootLogger.removeHandler(handler);
}
rootLogger.addHandler(rootHandler);
}
@Override
public void close() {
}
@Override
public void flush() {
}
@Override
public void publish(LogRecord record) {
if (!super.isLoggable(record))
return;
String name = record.getLoggerName();
int maxLength = 30;
String tag = name.length() > maxLength ? name.substring(name.length() - maxLength) : name;
try {
int level = getAndroidLevel(record.getLevel());
Log.println(level, tag, record.getMessage());
if (record.getThrown() != null) {
Log.println(level, tag, Log.getStackTraceString(record.getThrown()));
}
} catch (RuntimeException e) {
Log.e("AndroidLoggingHandler", "Error logging message.", e);
}
}
static int getAndroidLevel(Level level) {
int value = level.intValue();
if (value >= 1000) {
return Log.ERROR;
} else if (value >= 900) {
return Log.WARN;
} else if (value >= 800) {
return Log.INFO;
} else {
return Log.DEBUG;
}
}
}
Дальше непосредственно в месте применения в активити или фрагменте в onCreate инициализировать след. образом:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidLoggingHandler.reset(new AndroidLoggingHandler());
java.util.logging.Logger.getLogger("my.category").setLevel(Level.FINEST);
}
В таком случае будет видно реальное количество раз эмита всех событий.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Привет! В общем, создал бота для Telegram на javaПришло время деплоя
Используя WebView наткнулся на такой баг, что при долгом нажатии не появляется "менюшка" для работы с текстом(Коп, Встав и ТД)В Google информация...
Есть программа написанная на JAVAJar файл обернут Launch4j и сделан инсталятор Inno Setup
Стандартный контроллер может ставить на паузу и перематыватьНужно добавить кнопку полноэкранного режима и пару других