首页 文章

在Android中线程化UI更新

提问于
浏览
6

我刚刚开始使用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();
        }
    }
}

它工作正常但每个人都说在主线程中做你的图形,所以我正在尝试(并且失败)将它传递给另一个线程 . 麻烦的是,我完全不知道为什么我从未使用Threads .

Google使用Threads提供的示例似乎并不十分清楚,我无法按照我想要的方式执行此操作 . 请问有人在这里给我一个最基本的例子,说明如何使用Threads有效地做我在这里做的事情?

提前致谢 :)

4 回答

  • 1

    好吧,我想这里有一些混乱 . 你必须从主线程(也称为GUI线程)进行GUI更新 - 否则你会得到类似“Exception,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 .

  • 4

    您可以使用 AsyncTask 进行线程化,基础知识:painless threading,例如:Multithreading For Performance .

    要更新UI使用更新处理程序,请查看this . 每次要更新UI时,都会从线程向主ui线程发送消息 .

  • 1

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

  • 7

    您可能最终会使用您提供的代码对invalidate()(以及重绘)进行大量不必要的调用 . 最好使用处理程序触发y参数(和invalidate)的更改,您也可以触发延迟 .

相关问题