Форум программистов, компьютерный форум CyberForum.ru

Программирование Android

Войти
Регистрация
Восстановить пароль
 
кверти
4 / 4 / 1
Регистрация: 22.09.2013
Сообщений: 148
Завершенные тесты: 2
#1

Непонятное поведение многопоточного приложения - Программирование Android

12.05.2016, 20:00. Просмотров 273. Ответов 8
Метки нет (Все метки)

Всем добрый день. Ввожу в курс дела: я пишу игру под android и мне потребовалась в игре небольшая система, которая будет рендерить пул объектов хранящийся в HashMap<Integer, Object>.
Эта мапа заполняется в отдельном потоке. Элементы в мапу добавляются с небольшим промежутком времени(чтобы потом рендерились не все объекты сразу)
Вот код метода run();
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
    public void run() {
        if(!shotdown) {
            for(int i = 0; i < sizeArray; i++) {
                try {
                    Thread.sleep(100);
                    dummies.put(position, new Dummy(BodyFactory.createDummy(world)));
                    position++;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        shotdown = !shotdown;
    }
Код тривиален... каждые 100 мс добавляем в мапу объект, который в дальнейшем будет рендериться

Для дальнейшего понимания: Есть некоторый класс Level унаследованный от Thread, соответственно код выше относится к этому классу
Объект класса Level создается в классе отвечающем за игровой мир. Вот код этого класса
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
public class PlayState extends State {
    private float frameCount;
    private World world;
    private Box2DDebugRenderer debugRenderer;
    private OrthographicCamera camera;
    private Level level;
    private SpaceShip spaceShip;
 
    public PlayState(GameStateManager gsm) {
        super(gsm);
        frameCount = 0;
        Constans.WIDTH = Gdx.graphics.getWidth();
        Constans.HEIGHT = Gdx.graphics.getHeight();
 
        world = new World(Constans.GRAVITY, Constans.SLEEP);
        world.setContactListener(new ContactObject());
 
        camera = new OrthographicCamera(Constans.WIDTH / 2, Constans.HEIGHT / 2);
        camera.position.set(new Vector2(100.0f, 100.0f), 0);
 
        debugRenderer = new Box2DDebugRenderer();
 
        level = new Level(world);
        level.start();
        spaceShip = new SpaceShip(BodyFactory.createSpaceShip(world));
    }
 
    @Override
    protected void handleInput() throws InterruptedException {
        if(Gdx.input.getX() >= 0 && Gdx.input.getX() <= 40 && Gdx.input.getY() >= Constans.HEIGHT -45 && Gdx.input.getY() <= Constans.HEIGHT +30) {
            dispose();
            gsm.set(new MenuState(gsm));
        }
 
        if(spaceShip != null) {
            if (Constans.STYLE_CONTROL) {
                spaceShip.tapControl();
            } else {
                spaceShip.AccControl();
            }
        }
    }
 
    @Override
    public void update(float time) throws InterruptedException {
        camera.setToOrtho(false, Constans.WIDTH / 2, Constans.HEIGHT / 2);
        handleInput();
 
        if(spaceShip != null) {
            spaceShip.update(time);
        }
        for (Map.Entry entry : level.getDummies().entrySet()) {
            if(entry != null && entry.getValue() instanceof Dummy) {
                level.checkScreen(entry.getValue(), level.getPosition());
                Dummy dummy = (Dummy) entry.getValue();
                level.setPosition((Integer) entry.getKey());
                dummy.update(time);
            }
        }
    }
 
    @Override
    public void render(SpriteBatch batch) throws InterruptedException {
        world.step(1f, 2, 2);
        debugRenderer.render(world, camera.combined);
        batch.setProjectionMatrix(camera.combined);
        batch.begin();
        frameCount += Gdx.graphics.getDeltaTime();
        batch.draw(Constans.BG_PLAY_SCREEN.getKeyFrame(frameCount, true),0, 0);
 
        if(spaceShip != null) {
            batch.draw(spaceShip.getParameters().getTypeShip(), spaceShip.getPosition().x, spaceShip.getPosition().y);
        }
        for (Map.Entry entry : level.getDummies().entrySet()) {
            if(entry != null && entry.getValue() instanceof Dummy) {
                level.checkScreen(entry.getValue(), level.getPosition());
                Dummy dummy = (Dummy) entry.getValue();
                level.setPosition((Integer) entry.getKey());
                batch.draw(dummy.getParameters().getSkin(), dummy.getPosition().x, dummy.getPosition().y);
            }
        }
 
        batch.draw(Constans.SETTING_PLAY_SCREEN, 0, 0);
        batch.end();
    }
 
    @Override
    public void dispose() {
        if(spaceShip != null) {
            spaceShip.resetParameters();
        }
        if(level != null) {
            level.stop();
            level.dispose();
        }
    }
}
В методе update и render мы пробегаемся по всем объектам нашего пула и вызываем соответствующие методы для обновления и рендеринга каждого объекта.
На словах все вроде бы не сильно сложно. Но по итогам такого алгоритма возникает куча непонятных проблем.
1) Игра крашится, спустя некоторое количество отрисованых объектов
2) Методы update и render у объектов, которые отрисовываются отрабатывают не до конца.
А конкретно выглядит это так: объект отрисовался прошло 100мс(время указанное в методе run) и он исчезает. После отрисовывается другой объект. Почему так происходит? Ведь каждый элемент пула ссылается на разные объекты, а не на один и тот же.
В логах нет никаких вылетов ошибок и прочего. Приложение просто останавливается и все...
Буду благодарен за помощь.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.05.2016, 20:00     Непонятное поведение многопоточного приложения
Посмотрите здесь:

Непонятное поведение ArrayList - Программирование Android
У меня есть код, который циклом достаёт данные из базы данных и помещает их в HashMap, а оттуда уже типа HashMap помещает в ArrayList....

Непонятное поведение программы! - Программирование Android
есть счетчик, который выводит цифры в TextView (подобие секундомера) есть кнопка запуска, она же остановки счетчика. Кнопка...

Непонятное поведение при повороте экрана - Программирование Android
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.listpick); ...

Непонятное отображение spinner - Программирование Android
Здравствуйте! &lt;TableRow android:id=&quot;@+id/tableRow3&quot; android:layout_width=&quot;match_parent&quot; ...

Не понятное поведение BaseAdapter - Программирование Android
Добрый день! Проблема в следующем: есть ListView, есть адаптер унаследованный от BaseAdapter. В адаптере в методе getView загружаю...

Неадекватное поведение адаптера ListView - Программирование Android
Собственно есть кастом-адаптер. В него приходят два массива с данными. В dates находится даты в формате &quot;29.05.15&quot;. В photos ссылки на...

Анимация ViewGroup, некорректное поведение кнопки - Программирование Android
Всем привет. Возникла такая проблема. Есть анимация, по клику - блок отодвигается вправо, показывая то, что под ним. Кнопка, запускающая...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Alexvp
107 / 71 / 8
Регистрация: 03.08.2014
Сообщений: 344
13.05.2016, 09:50     Непонятное поведение многопоточного приложения #2
Конечно, это ваше личное дело. Но зачем изобретать велосипед? Возьмите, например, движок LibGDX, где все эти процессы нижнего уровня хорошо реализованы и протестированы. И сосредоточьтесь на gameplay своей игры.
vxg
Модератор
3112 / 1914 / 206
Регистрация: 13.01.2012
Сообщений: 7,309
13.05.2016, 10:03     Непонятное поведение многопоточного приложения #3
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от кверти Посмотреть сообщение
Почему так происходит?
вы добавляете в мап объекты в потоке и перебираете этот же мап в другом потоке что бы отрисовать элементы - откуда уверенность в том что мап потокобезопасен и его не расторащит от одновременного перебора и добавления? где Semaphore на худой случай?
кверти
4 / 4 / 1
Регистрация: 22.09.2013
Сообщений: 148
Завершенные тесты: 2
13.05.2016, 12:47  [ТС]     Непонятное поведение многопоточного приложения #4
Спасибо за ответ. А можно узнать какие классы в libGdx позволяют реализовать данный механизм? Дело в том, что я взял за основу этот фреймворк, но, видимо, плохо в нем еще ориентируюсь

Добавлено через 42 секунды
Спасибо, попробую
Pablito
2411 / 1856 / 581
Регистрация: 12.05.2014
Сообщений: 6,591
Завершенные тесты: 1
13.05.2016, 14:42     Непонятное поведение многопоточного приложения #5
Сообщение было отмечено автором темы, экспертом или модератором как ответ
http://developer.android.com/intl/ru...ntHashMap.html
https://habrahabr.ru/post/132884/
Alexvp
107 / 71 / 8
Регистрация: 03.08.2014
Сообщений: 344
13.05.2016, 20:20     Непонятное поведение многопоточного приложения #6
Цитата Сообщение от кверти Посмотреть сообщение
А можно узнать какие классы в libGdx позволяют реализовать данный механизм
В сети навалом неплохих уроков по этому движку.
Одно могу сказать, что большое число объектов рендить накладно.
vxg
Модератор
3112 / 1914 / 206
Регистрация: 13.01.2012
Сообщений: 7,309
14.05.2016, 00:42     Непонятное поведение многопоточного приложения #7
Цитата Сообщение от Alexvp Посмотреть сообщение
Одно могу сказать, что большое число объектов рендить накладно.
позвольте с вами в этом вопросе согласиться и довести мысль до логического завершения - минимальная нагрузка на процессор будет если не рендерить вообще ничего
Alexvp
107 / 71 / 8
Регистрация: 03.08.2014
Сообщений: 344
14.05.2016, 13:23     Непонятное поведение многопоточного приложения #8
Цитата Сообщение от vxg Посмотреть сообщение
минимальная нагрузка на процессор будет если не рендерить вообще ничего
Логично
Уменьшение числа объектов можно делать за счет их группировки, но это зависит от геймплея игры. Однажды мне пришлось часть объектов включать в фоновый рисунок, так как они должны были быть на экране, но не были активными. Таким образом, вместо полутора десятков объектов рендился только один.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.05.2016, 17:24     Непонятное поведение многопоточного приложения
Еще ссылки по теме:

Sockets и потоки, разное поведение на устройствах - Программирование Android
Привет всем. Такая проблема - пытаюсь создать сокеты и обменяться словами. Код сервера public class ServerActivity extends...

Странное поведение swipe-to-dismiss RecyclerView - Программирование Android
После удаления свайпом элемента списка остаётся небольшой пробе между элементами, сложно объяснить, поэтому вот ссылка на то, что...

Поведение после смены ориентации экрана - Программирование Android
Доброго времени суток. У меня есть 2 xml layout файла для вертикальной и горизонтальной ориентации дисплея c тем самим набором елементов....

Распознавание речи и клавиатура - время ожидания - необычное поведение - Программирование Android
Столкнулся с необычной проблемой. Использую распознавание речи.. То есть при нажатии кнопки открывается окно диктования и после...

Непонятное поведение ОС - Windows 7
Здрасте! Купил новый комп, а он загружается через раз (чаще через несколько раз), выключается долго, и один раз не вышел из спячки. ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
vxg
Модератор
3112 / 1914 / 206
Регистрация: 13.01.2012
Сообщений: 7,309
14.05.2016, 17:24     Непонятное поведение многопоточного приложения #9
Alexvp, если он рендерился то без разницы сколько вы напихали единиц в группу а если это рисунок то и ежу понятно что нет нужды бить фон на 1000 элементов
Yandex
Объявления
14.05.2016, 17:24     Непонятное поведение многопоточного приложения
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru