Запутался по поводу "реализует Runnable" - PullRequest
2 голосов
/ 08 января 2012

Здравствуйте, у меня есть только несколько дней с Java и Android здесь. Я немного озадачен тем, как именно работает «реализует работоспособность», например:

public class DrawableSurfaceView extends SurfaceView implements Runnable {

[...]

public void resume(){
    isRunning = true;
    mThread = new Thread(this);
    mThread.start(); //start the animation
    parseParameters(); //<== Here is my problem
}

public void run() {
    while (isRunning == true){
        if (!mHolder.getSurface().isValid()) {
         continue;
        }
        Canvas canvas = mHolder.lockCanvas();
        canvas.drawARGB(255, 0, 0, 0);
        canvas.drawPath(PenPath, PenPaint);
        canvas.drawPath(CursorPath, CursorPaint);
        mHolder.unlockCanvasAndPost(canvas);
    }
}
public void parseParameters() {
  [...]
  [ The rest of my code here  modifying PenPath and CursorPath, etc ]

}

Мне стыдно спрашивать, но я подумал, что после mThread.start (); новый поток будет запущен, запустив цикл в методе run. вместо этого я получаю метод run, выполняемый только после завершения метода parseParameters (). Чего я хотел добиться, так это иметь холст в потоке цикла рисования и внешне изменять параметры путей рисования для генерации моей анимации. Я уверен, что это очень элементарно, но я не мог понять это в течение нескольких часов. Документы не помогают.

Любой указатель очень помог бы. Ура ребята!

Ответы [ 5 ]

6 голосов
/ 08 января 2012

Значение implements Runnable состоит в том, что этот класс реагирует на методы, определенные в интерфейсе Runnable, и они могут быть переданы в конструктор Thread, как и вы.

Теперь новый поток выполняется не сразу, и вполне возможно, что текущий поток продолжит выполнение какой-либо функции, прежде чем система переключится на контекст другого потока.

5 голосов
/ 08 января 2012

mThread.start(); только говорит Java (и ОС), чтобы сделать поток пригодным для запуска. Там нет никакой гарантии, что поток начнется сразу. На самом деле, особенно в одноядерной системе, поток часто не запускается до следующего запуска ОС и переключения задач / потоков, поэтому, когда он действительно запустится, может быть довольно ", когда он чувствует себя так, как нужно. ».

3 голосов
/ 08 января 2012

Class X ... implements Runnable делают только одну вещь, а именно обещают, что X предоставит то, что, по словам интерфейса Runnable, будет там.Другими словами, это признак того, что X будет соответствовать контракту , что интерфейс Java - здесь Runnable - это.

Для Runnable единственное, что в контракте сказано, это то, чтоX предоставит метод void run().

Хитрость заключается в том, что для вызова вызываемого конструктора Thread требуется Runnable, поэтому можно быть уверенным, что существует метод run() для вызова.Обратите внимание, что когда новый поток начался, ваша программа теперь имеет два места, где что-то происходит.Вы должны быть уверены, что правильно назначаете работу, поэтому это происходит в правильном потоке.

2 голосов
/ 08 января 2012

Ваше понимание Runnable в основном верно.

Проблема в том, что вы делаете неправильные предположения о том, что делает Thread.start().В действительности Thread.start () вызывает создание нового собственного потока и его стека и заставляет поток допускать для запуска.Но зависит от реализации , запланирован ли новый поток и выполняется ли до того, как вызов start вернется к исходному потоку ... или нет.

Другая проблема с вашим кодом состоит в том, чтоrun() метод по сути является циклом опроса ЦП.Если вы не работаете на платформе с несколькими ядрами, поведение вашего приложения будет очень "запаздывающим" ... и оно будет быстро разряжать батареи.Вы должны сделать его управляемым событиями, с методом run(), ожидающим, пока не будет что-то реально нарисовать.

Я не знаю достаточно об Android, чтобы рассказать вам, как это реализовать, но каково ваше приложениев настоящее время это выглядит очень неправильно для меня.

0 голосов
/ 08 января 2012

Похоже, что в этой ситуации вы не захотите создавать какие-либо циклы самостоятельно. Вы хотели бы переопределить onDraw (Canvas canvas) в своем пользовательском представлении. При этом вы можете принудительно вызвать onDraw, вызвав invalidate () для вашего представления из любого места. Вы также можете принимать параметры из внешнего источника.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...