2013-05-21 4 views
0

Я разрабатываю игровой движок Android, используя SurfaceView для рисования растровых изображений, с аналогичной структурой для LunarLander. Моя основная деятельность игрового движка создает макет такой, что должны отображать класс расширения SurfaceView, как показано ниже:(SurfaceHolder.Callback) surfaceCreated никогда не назывался

super.onCreate(savedInstanceState); 

    setContentView(R.layout.ss_layout); 

    SSSurfaceView ssSurfaceView = (SSSurfaceView)findViewById(R.id.surface_view); 
    SSSurfaceView.SSViewThread renderThread = 
     (SSSurfaceView.SSViewThread) ssSurfaceView.getThread();  

Метод findViewById успешно возвращает экземпляр моего класса расширения SurfaceView, и я могу запустить нить я определить внутри класса, который создается в этом методе, конструктор класса:

public SSSurfaceView(Context context, AttributeSet attributes) 
{ 
    super(context, attributes); 

    SurfaceHolder holder = getHolder(); 
    holder.addCallback(this); 

    thread = new SSViewThread(holder, context); 
} 

конструктор должен быть получения ссылки на связанный SurfaceHolder, которые он затем переходит к нити строи тор. У меня возникла проблема внутри метода запуска потока, где owner.lockCanvas (null) возвращал значение null. Я где-то читал, что это может означать, что поверхность не была создана, поэтому я добавил оператор if, используя логическое значение, которое я установил для true в обратном вызове surfaceCreated.

public void run() 
    { 
     Canvas canvas = null; 
     try 
     { 
      canvas = holder.lockCanvas(null); 
      //I added the condition below 
      if(surfaceCreated) 
      { 
       drawAll(canvas); 
      } 
     } 
     catch(Exception e) 
     { 
      Log.wtf("SurfaceView", "exception"); 
     } 
     finally 
     { 
      if(canvas != null) 
      { 
       holder.unlockCanvasAndPost(canvas); 
      } 
     } 
    } 

А вот обратный вызов:

public void surfaceCreated(SurfaceHolder holder) 
{ 
    surfaceCreated = true; 
} 

И, как выясняется, surfaceCreated никогда не вызывается. Мое приложение отображает серый экран и ничего не делает, поскольку метод drawAll никогда не повторяется. Вот файл layout.xml для загрузки:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" > 

    <com.bostonwalker.sseng.SSSurfaceView 
     android:id="@+id/surface_view" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 

</FrameLayout> 

EDIT: Это не мой весь код, я попытался ограничить свои примеры в соответствующих разделах. Поток вызывается в основном цикле, но с учетом времени обратный вызов никогда не срабатывает.

EDIT: Вот цикл итеративно в потоке пользовательского интерфейса:

while(!halt) 
    { 
     //EDIT: Changed from .run() to .start() 
     renderThread.start(); 
     gameThread.start(); 
     //Wait for both threads to proceed before continuing 
     try 
     { 
      renderThread.join(); 
      gameThread.join(); 
     } 
     catch (InterruptedException e) 
     { 
      //Do nothing 
     } 

     Thread.currentThread(); 
     try 
     { 
      Thread.sleep(2); 
     } 
     catch (Exception e) 
     { 
      //Do nothing 
     } 
    } 
+0

извините, но ваш 'while (! Halt)' цикл и контент выглядят действительно злобно ... конечно, вам нужно сделать это именно так? – WarrenFaith

+0

Хотя это не проблема, я ценю вашу заботу. На данный момент меня не интересует оптимизация или даже гибкость, просто с получением моего SurfaceView для отображения и обратного вызова для запуска. –

ответ

1

Ваш рисунок нить не цикл - это только выполняется один раз и выходит. И, вероятно, поверхность еще не создана в этом первом запуске.

Вам нужно поместить код, который вы в настоящее время есть в каком-то цикле, например, (в псевдокоде):

while(!done) { 
    lockTheCanvas(); 
    drawAFrame(); 
    unlockTheCanvas(); 
    sleep(FRAME_INTERVAL); 
} 

Затем нужно прекратить поток в соответствующее время установка «сделано» на true; Обратите внимание, что вам нужен sleep(), иначе ваш поток будет запускать процессор и никогда не будет завершен.

+0

Нить активируется 10 раз в секунду первичным контуром и, по крайней мере, делает эту часть безупречной. Моя проблема в том, что поверхность НИКОГДА не создается или, по крайней мере, что обратный вызов никогда не срабатывает. –

+0

Я бы с подозрением относился к тому, как вы активируете поток 10 раз в секунду. Является ли цикл, который вы используете, чтобы сделать это соответствующим образом (спящим), чтобы вызвать обратный вызов? Кроме того, почему есть поток, который только запускается один раз, а затем выходит, а затем вызывает его несколько раз? Вероятно, было бы лучше просто позволить потоку работать непрерывно до тех пор, пока не прервется, как в моем примере с псевдокодом. – GreyBeardedGeek

+0

Это немного упрощено, но я отправил цикл, итератированный в потоке пользовательского интерфейса (основное действие .java). –

Смежные вопросы