For loop causes exception

0

I want to draw an animation with text as described in code in draw() method.

    if (condition)
        for(int i=0; i<50; i++)
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j <= 100; j++) {
                        try {
                            Thread.sleep(10);
                            canvas.drawText("miss", (float) chibi1.getX(), (float) chibi1.getY()-i, pt.pBlack);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();

It works fine until probably it reaches the last iteration.

Error looks like this:

2019-11-30 1317.295 16294-16383/pl.jawegiel.grarpg.pl.jawegiel.grarpg A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 16383 (Thread-36), pid 16294 (jawegiel.grarpg) 2019-11-30 1317.361 16414-16414/? A/DEBUG: pid: 16294, tid: 16383, name: Thread-36 >>> pl.jawegiel.grarpg.pl.jawegiel.grarpg <<< 2019-11-30 1317.676 16414-16414/? E/crash_dump64: Normal dump:pl.jawegiel.grarpg.pl.jawegiel.grarpg 2019-11-30 1317.727 1393-1832/? E/InputDispatcher: channel '574dd1 pl.jawegiel.grarpg.pl.jawegiel.grarpg/pl.jawegiel.grarpg.activities.Gra (server)' ~ Channel is unrecoverably broken and will be disposed! 2019-11-30 1317.750 1393-1832/? E/InputDispatcher: channel '6cb9262 pl.jawegiel.grarpg.pl.jawegiel.grarpg/pl.jawegiel.grarpg.activities.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed! 2019-11-30 1317.751 814-814/? E/ANDR-IOP: IOP HAL: Received pkg_name = pl.jawegiel.grarpg.pl.jawegiel.grarpg pid = 0 2019-11-30 1317.928 1393-1475/? E/ActivityManager: Sending non-protected broadcast com.sonymobile.crashmonitorsystemservice.DIR_UPDATED from system 1393:system/1000 pkg android java.lang.Throwable at com.android.server.am.ActivityManagerService.checkBroadcastFromSystem(ActivityManagerService.java:21850) at com.android.server.am.ActivityManagerService.broadcastIntentLocked(ActivityManagerService.java:22459) at com.android.server.am.ActivityManagerService.broadcastIntent(ActivityManagerService.java:22601) at android.app.ContextImpl.sendBroadcastAsUser(ContextImpl.java:1224) at android.app.ContextImpl.sendBroadcastAsUser(ContextImpl.java:1196) at android.content.ContextWrapper.sendBroadcastAsUser(ContextWrapper.java:525) at com.sonymobile.crashmonitor.system.service.DumpfileObserver.onEvent(DumpfileObserver.java:32) at android.os.FileObserver$ObserverThread.onEvent(FileObserver.java:123) at android.os.FileObserver$ObserverThread.observe(Native Method) at android.os.FileObserver$ObserverThread.run(FileObserver.java:86)

Why it happens and what to change?

0

canvas most likely isn't thread safe and mustn't be used from many threads at once.

0

Więc co można zrobić w tej sytuacji?

0

Najważniejsze pytanie brzmi: dlaczego w ogóle chcesz rysować coś z wielu wątków jednocześnie?

0

Żeby nie blokować głównego wątku UI. Używam przecież w tej pętli Thread.sleep(), ale może faktycznie coś namieszałem. Mógłbyś proszę przedstawić działający kod?

Edit: Częściowo rozwiązane, ta zewnętrzna pętla zupełine niepotrzebna. Jak klikam szybko kilka razy to tworzonych jest wiele wątków zupełnie niepotrzebnie zamiast jednego nowego, jak się przed tym ustrzec?

0

Uzycie Thread.sleep w „produkcyjnym” kodzie wskazuje na to, że coś poszło nie tak. Możesz zakolejkować polecenia używając puli wątków z 1 wątkiem, jeśli nie chcesz tworzyć ich N.

0

Czy mógłbym Was prosić o przedstawienie tego w kodzie?

0

A możesz przedstawić, co chcesz osiągnąć? Zacząłeś dyskusje od przedstawienia snippetu z jakimś forem - nie wiemy, jaki problem rozwiązujesz i na jakiej platformie (rozumiem, że Android?).

0

Platforma Android jak wskazuje jeden z tagów. Chodzi mi o prostą rzecz czyli o to, że chcę stworzyć animację narysowanego na ekranie tekstu canvas.drawText(), który to napis przesunie się w górę o określoną wysokość z jakimś tam delay.

1

Może coś takiego?

threadPool.submit(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    Thread.sleep(1000); // 1s
                    canvas.drawText("miss", (float) chibi1.getX(), (float) chibi1.getY()-i, pt.pBlack);
                }
            }
        });

gdzie threadPool = Executors.newFixedThreadPool(1);
Ewentualnie fajnie by było zamiast sleepa, który blokują wątek, zwrócić go do puli, aby mógł obsłużyć nowe kliknięcie, ale na szybko nie umiem tego zrobić bez rxJavy :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1