Обновление View во время выполнения в Android - PullRequest
4 голосов
/ 21 декабря 2010

Пример довольно прост: я хочу, чтобы пользователь знал о том, что делает приложение, просто показывая текст (canvas.drawText ()). Затем появляется мое первое сообщение, но не другие. Я имею в виду, у меня есть метод "setText", но он не обновляется.

onCreate(Bundle bundle) {
    super.onCreate(bundle);
    setContentView(splash); // splash is the view class
    loadResources();
    splash.setText("this");
    boundWebService();
    splash.setText("that"):
    etc();
    splash.setText("so on");
}

Рисование текста в представлении работает, просто используя drawText в onDraw (); таким образом, setText изменяет текст, но не показывает его.

Кто-то порекомендовал мне заменить представление на SurfaceView, но было бы много проблем всего за пару обновлений, ТАК ... как, черт возьми, я могу динамически обновлять представление во время выполнения?

Это должно быть довольно просто, просто показывать текст, скажем, 2 секунды, а затем основной поток выполняет свои действия, а затем обновляет текст ...

Спасибо!

Обновление:

Я пытался реализовать handler.onPost (), но снова и снова та же история. Позвольте мне поставить вам код:

public class ThreadViewTestActivity extends Activity {

Thread t;
Splash splash;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    splash = new Splash(this);
    t = new Thread(splash);
    t.start();

    splash.setTextow("OA");
    try { Thread.sleep(4000); } catch (InterruptedException e) { }
    splash.setTextow("LALA");
}       
}

И

public class Splash implements Runnable {

Activity activity;
final Handler myHandler = new Handler();

public Splash(Activity activity) {
    this.activity=activity;
}   

@Override
public void run() {
    // TODO Auto-generated method stub

}

public synchronized void setTextow(final String textow) {
    // Wrap DownloadTask into another Runnable to track the statistics
    myHandler.post(new Runnable() {
        @Override
        public void run() {
            TextView t = (TextView)activity.findViewById(R.id.testo);
            t.setText(textow);
            t.invalidate(); 
        }                   
    });
}
}

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

Ответы [ 3 ]

5 голосов
/ 22 декабря 2010

Я еще не достиг этого, но я думаю, что обычным способом является длительная инициализация в фоновом потоке и использование Handler.post() для обновления пользовательского интерфейса.См. http://developer.android.com/reference/android/widget/ProgressBar.html для другого, но, возможно, связанного примера.

Также см. этот ответ , особенно первый абзац:

Проблемаскорее всего, вы запускаете заставку (какой-то диалог, такой как ProgressDialog, я полагаю) в том же потоке, что и вся выполняемая работа.Это будет препятствовать обновлению представления заставки, что может препятствовать его отображению на экране.Вам нужно отобразить заставку, запустить экземпляр AsyncTask, чтобы загрузить все ваши данные, а затем скрыть заставку после завершения задачи.

Обновление (на основена ваше обновление и ваш комментарий): вы не должны обновлять пользовательский интерфейс в какой-либо теме, кроме той, где создается ваша активность.Почему вы не можете загрузить свои ресурсы в фоновом потоке?

1 голос
/ 23 декабря 2010

Первое: onCreate выполняется в основном потоке пользовательского интерфейса приложения, поэтому обновления пользовательского интерфейса не выполняются, пока вы не покинете его. По сути, вам нужен один поток для выполнения долгосрочных задач и какой-то механизм для загрузки обновлений в пользовательский интерфейс.
Самый обычный подход - расширить AsyncTask, см. эту ссылку для получения дополнительной информации

0 голосов
/ 21 декабря 2010

Я полагаю, что ваше представление является расширенным, и вы вызываете onDraw для его рисования, поэтому, возможно, представление не «обновляет» их состояние, поэтому попробуйте это

onCreate(Bundle bundle) {
    setContentView(splash); // splash is the view class

    loadResources();
    splash.setText("this");
    splash.invalidate();
    boundWebService();
    splash.setText("that"):
    splash.invalidate();
    etc();
    splash.setText("so on");
    splash.invalidate();
}
...