在Android中线程UI更新

我刚刚开始使用android开发并更新UI真的让我感到困扰:/

这是我迄今为止的工作 -


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();
        }
    }
}

它工作正常,但每个人都说在主线程中做图形,所以我试图(和失败)将它传递给另一个线程。 麻烦的是,我完全不知道,因为我从来没有使用过线程。

Google给出的有关使用线程的示例似乎并不十分清晰,我也无法真正按照自己的想法遵循它。 我可以问一个人在这里给我一个最基本的例子,说明我如何能够有效地使用线程来做我在这里做的事情?

提前致谢 :)


好吧,我猜这里有一些混乱。 您必须从主线程(也称为GUI线程)执行GUI更新 - 否则您会收到类似“异常,blabla泄漏了视图”的内容。

我想大家误解的是,昂贵的操作,比如联网,应该在与主线程不同的线程中完成。 如果你想从网络线程更新GUI,你会像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();
        }
    }

使用onDraw()中的invalidate()旧代码,即使在没有更改的情况下,您仍然会重新绘制gui。

新代码的重要部分是postInvalidate() 。 这可以告诉GUI线程 - 从另一个线程 - 重新绘制GUI。


您可以使用AsyncTask进行线程化,基本知识如下:无痛线程,例如:Multithreading For Performance。

要更新UI使用更新处理程序,请看看这个。 每次你想更新UI时,你都会从线程发送一条消息到你的主UI线程。


那么第一个问题是 - 为什么你想在一个单独的线程中做你的图形? 因为除非你正在做某些特定的事情(主要是在游戏或媒体领域),否则如果你尝试这样做,你会发现自己处于很多痛苦中,没有什么益处。

链接地址: http://www.djcxy.com/p/31447.html

上一篇: Threading UI updates in Android

下一篇: How to add Canvas in a specific LinearLayout?