Начал учить яву. Написал простенькую рисовалку для планшета, пару классов для 2D-анимированных спрайтов, оптимистично кинулся портировать игрушки с javaScript Аха. ЩЩаз :)
Внезапно обнаружил, что если я создаю поток - наследник Thread то из него не получается управлять объектами класса MediaPlayer ! Причём я могу создать объект, запустить на проигрывание, но методы stop() и pause() ни чего не делают, а метод release() вызывает ошибку :(
Ничего не работает, даже если я пытаюсь всё делать методами основного потока, вызывая их из другого. Видимо я не въезжаю в какой-то фундаментальный момент.
Может быть кто подскажет?
Добавлено (31 октября 2015, 14:10) --------------------------------------------- Пока выяснил, что сложные объекты нужно создавать и использовать в каждом потоке свои. Обмен между потоками нормально работает только для примитивов.
Может я чего перемудрявываю? Главным потоком только создаю отдельный поток для расчётов и отдельный поток для графики.
Пару вопросов: 1. Где создаешь объект класса MediaPlayer - в главном потоке или в каком-то дочернем? 2. Работают ли эти методы, если они будут вызваны из главного потока?
Если создаю в главном и вызываю из главного работает Если создаю в дочернем и вызываю из дочернего - работает Если создаю в главном, вызываю из дочернего - не работает Если создаю в дочернем, вызываю из главного - не работает
Причём не важно, обращаюсь я напрямую к public экземпляру или через метод класса - всё равно не работает.
В данный момент приспособился, вызываю только из метода run() того потока в котором создавал, тогда всё работает.
Добавлено (04 ноября 2015, 22:40) --------------------------------------------- Наврал Нихрена не работает
Я не силен в разработке Java приложений (больше как-то с Java EE работаю), но помню, когда еще на 2-ом курсе писали приложения на C#, там такая же штука была - нельзя было вызывать методы объектов из других процессов. Для решения этого момента была какая-то ужасная конструкция, уже не помню, что она собой представляла. Но факт остается фактом - нельзя вызывать некоторые методы объектов, относящихся к интерфейсу из другого потока.
На StackOverflow (ссылка) есть решение. Из него следует, что нужно иметь поток (либо создать его, либо использовать родительский), который будет создавать нужные тебе объекты (вдруг у тебя больше одного объекта MediaPlayer), и ждать от других потоков обработчики событий, чтобы исполнить их в контексте своего потока.
Чтобы адаптировать это решение к твоей задаче, можно сделать примерно так:
1. Сначала определить обработчик события
Код
public interface MediaPlayerInvoker { public void run(MediaPlayer player); }
2. Определить класс с интерфейсом Runnable, чтобы запустить его в отдельном потоке
Код
public class Invoker implements Runnable { public static final BlockingQueue<MediaPlayerInvoker> queue = new LinkedBlockingQueue<MediaPlayerInvoker>();
private MediaPlayer mediaPlayer;
public Invoker() { mediaPlayer = new MediaPlayer(); //Или как он там создается }