简体   繁体   English

在Android中线程化UI更新

[英]Threading UI updates in Android

I've just started with android development and updating the UI is really bugging me :/ 我刚刚开始使用android开发和更新UI真的很烦我:/

This is what I've got working so far - 这就是我到目前为止所做的工作 -

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

It works fine but everybody says that doing your graphics in the main thread, so I'm trying (and failing) to pass it off to another thread. 它工作正常,但每个人都说在主线程中做你的图形,所以我正在尝试(并且失败)将它传递给另一个线程。 Trouble is, I have absolutely no idea how since really I've never used Threads. 麻烦的是,我完全不知道为什么我从未使用Threads。

The examples that Google gives on using Threads doesn't seem to be very clear and I couldn't really follow it for what I want to do. Google使用Threads提供的示例似乎并不十分清楚,我无法按照我想要的方式执行此操作。 Could I ask somebody out here to give me the most basic example of how I could do what I'm doing here efficiently using Threads? 请问有人在这里给我一个最基本的例子,说明如何使用Threads有效地做我在这里做的事情?

Thanks in advance :) 提前致谢 :)

Well, I guess there is some confusion going on here. 好吧,我猜这里有一些混乱。 You HAVE TO do your GUI updates from the main thread (also called the GUI thread) - otherwise you well get something like "Exception, blabla has leaked a view". 你必须从主线程(也称为GUI线程)进行GUI更新 - 否则你会得到类似“异常,blabla泄露视图”的内容。

I guess what have misunderstood is that expensive operations, such as networking, should be done in a different thread than the main thread. 我想错误的是,昂贵的操作,例如网络,应该在与主线程不同的线程中完成。 And if you would like to update the GUI from the network thread you would do as ArtWorkAD says (or his links says). 如果您想从网络线程更新GUI,您可以像ArtWorkAD所说的那样(或者他的链接说)。

So for what you want to do, you could achieve with something like replacing your SimpleMotion class with the following: 因此,对于您想要做的事情,您可以使用以下内容替换您的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();
        }
    }

With your old code of having invalidate() in onDraw() you would continously be redrawing the gui even while there are no change to it. 使用onDraw()中的invalidate()旧代码,即使没有更改,也会不断重绘gui。

The important part of the new code is postInvalidate() . 新代码的重要部分是postInvalidate() This makes it possible to tell the GUI thread - from another thread - to redraw the GUI. 这使得可以告诉GUI线程 - 从另一个线程 - 重绘GUI。

You can use AsyncTask for threading, basics: painless threading , example: Multithreading For Performance . 您可以使用AsyncTask进行线程化,基础知识: 无痛线程 ,例如: 多线程性能

To update UI use update handlers, have a look at this . 要更新UI使用更新处理程序,请查看此内容 Everytime you want to update UI you send a message from the thread to your main ui thread. 每次要更新UI时,都会从线程向主ui线程发送消息。

Well the first question is -- why do you want to do your graphics in a separate thread? 那么第一个问题是 - 为什么你想在一个单独的线程中做你的图形? Because unless you are doing some specific things (mostly in the realm of games or media), you are going to find yourself in lots of pain with little benefit if you try to do that. 因为除非你正在做一些特定的事情(主要是在游戏或媒体领域),否则如果你试图这样做,你会发现自己陷入很多痛苦并没什么好处。

Your might end up with lots of unnecessary calls to invalidate() (and thus redraws) with the code you provide. 您可能最终会使用您提供的代码对invalidate()(以及重绘)进行大量不必要的调用。 Would be better to trigger the change of the y parameter (and the invalidate) with a handler, which you may also fire delayed. 最好使用处理程序触发y参数(和invalidate)的更改,您也可以触发延迟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM