Обновления пользовательского интерфейса в Android - PullRequest
6 голосов
/ 19 сентября 2010

Я только начал с разработки для Android, и обновление пользовательского интерфейса действительно вызывает у меня проблемы: /

Это то, что я до сих пор работал -


package projects.Move;

import android.os.Bundle;
import android.view.View;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Color;

public class Move extends Activity {

    private float y = 0;
    private long now = 0;  
    private float delay = 75;
    private Paint paint = new Paint();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new SimpleMotion(this));
        paint.setColor(Color.BLACK);
    }
    private class SimpleMotion extends View {

        public SimpleMotion(Context context) {
            super(context);
        }

        @Override protected void onDraw(Canvas canvas) {

            float x = canvas.getWidth() / 2;
            canvas.drawColor(Color.WHITE);
            canvas.drawCircle(x, y, 30, paint);  
            if(System.currentTimeMillis() - now > delay) y++;    
            invalidate();
        }
    }
}

Работает нормальноно все говорят, что делают вашу графику в главном потоке, поэтому я пытаюсь (и не могу) передать ее другому потоку.Проблема в том, что я абсолютно не представляю, как на самом деле я никогда не использовал Threads.

Примеры, которые Google приводит по использованию Threads, кажутся не очень ясными, и я не мог действительно следовать этомуЯ хочу делать.Могу ли я попросить кого-нибудь здесь дать мне самый простой пример того, как я могу сделать то, что я делаю здесь, эффективно, используя потоки?

Заранее спасибо:)

Ответы [ 4 ]

7 голосов
/ 20 сентября 2010

Ну, я думаю, здесь происходит некоторая путаница.Вы ДОЛЖНЫ выполнять обновления GUI из основного потока (также называемого потоком GUI) - в противном случае вы получите что-то вроде «Исключение, blabla утекла представление».

Я думаю, что неправильно поняли, что дорогие операцииНапример, работа в сети должна выполняться в другом потоке, нежели основной поток.И если вы хотите обновить графический интерфейс пользователя из сетевого потока, то вы будете делать то, что говорит ArtWorkAD (или его ссылки говорят).

Так что для того, что вы хотите сделать, вы можете достичь чего-то вроде замены вашего класса SimpleMotionсо следующим:

private class SimpleMotion extends View {

        public SimpleMotion(Context context) {
            super(context);

            new Thread(new Runnable() {
                public void run() {
                    while(true){
                        try {
                            Thread.sleep(75);
                            y++;
                            postInvalidate();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
              }).start();
        }

        @Override protected void onDraw(Canvas canvas) {

            float x = canvas.getWidth() / 2;
            canvas.drawColor(Color.WHITE);
            canvas.drawCircle(x, y, 30, paint);  
//            if(System.currentTimeMillis() - now > delay) y++;    
//            invalidate();
        }
    }

С вашим старым кодом, имеющим invalidate() в onDraw(), вы будете непрерывно перерисовывать графический интерфейс, даже если в нем нет изменений.

Важныйчасть нового кода postInvalidate().Это позволяет указать потоку GUI - из другого потока - перерисовать GUI.

4 голосов
/ 19 сентября 2010

Вы можете использовать AsyncTask для многопоточности, основы: безболезненная многопоточность , пример: Многопоточность для производительности .

Для обновления интерфейса пользователя используйте обновлениеобработчики, взгляните на this .Каждый раз, когда вы хотите обновить пользовательский интерфейс, вы отправляете сообщение из потока в ваш основной поток пользовательского интерфейса.

1 голос
/ 20 сентября 2010

У вас может возникнуть множество ненужных вызовов для аннулирования () (и, следовательно, перерисовки) с помощью предоставленного вами кода.Было бы лучше вызвать изменение параметра y (и аннулировать) с помощью обработчика, который вы также можете запустить с задержкой.

1 голос
/ 20 сентября 2010

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

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