更新的TextView使用的处理程序 [英] Updating TextView using handler

查看:198
本文介绍了更新的TextView使用的处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做一个简单的计数器计数从5到1和每秒更新后的视图。我试着这样做没有处理程序,并只是一个简单的循环,但它只是表明我1后等待或强制关闭。我曾尝试与 runOnUIThread 和线程太多搞乱,但我失去了一些东西。

下面是我的code:

 包com.ammad.test;
进口android.os.Bundle;
进口android.os.Handler;
进口android.app.Activity;
进口android.view.Menu;
进口android.view.MenuItem;
进口android.view.View;
进口android.widget.Button;
进口android.widget.TextView;
进口android.support.v4.app.NavUtils;公共类主要活动扩展{    TextView的电视;
    按钮B1;
    处理器mHandler;
    INT I = 5;
    私人Runnable接口可运行;    @覆盖
    公共无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_main);
        电视=(的TextView)findViewById(R.id.tvShow);
        B1 =(按钮)findViewById(R.id.bt1);        可运行=新的Runnable(){
            公共无效的run(){
                //做你的东西 - 不要在这里创建一个新的可运行!
                tv.setText(将String.valueOf(I));
                一世 - ;
                mHandler.postDelayed(可运行,500);            }
        };
        b1.setOnClickListener(新View.OnClickListener(){            公共无效的onClick(视图v){
                // TODO自动生成方法存根
                mHandler.post(可运行);
                mHandler.removeCallbacks(可运行);            }
        });    }    公共无效doTheLoop(){        / *
         * runOnUiThread(新的Runnable(){
         *
         *公共无效的run(){的for(int i = 5; I> = 1;我 - ){// TODO
         *自动生成方法存根tv.setText(Integer.toString(I));对于(INT
         * J = 0; J< 200000; J ++); }}
         *`输入code here`
         *});
         * /
        // mHandler.post(可运行);
    }
}


解决方案

你在哪里实例 mHandler ?我认为,code缺失,否则这将失败,一个NullPointerException异常。因为如果你只是用的onCreate 无参数的构造函数初始化它它会使用UI线程的消息队列中是很重要的。

有与这虽然其他问题:你的 Runnable.run 方法中,你实际上并没有检查 I 小于零,因此它总是会调用 postDelayed 与自身。此外,您更新的UI(的setText )从一个非UI线程,这可能会导致不确定的行为。

我觉得你的code是只是有点复杂得多,它需要的。如果这个例子是简单化并隐藏了您的实际意图,这是一个例子可能过于简单,但这里的东西,基本上工作,但你需要编辑一个位编译(捕捉InterruptedException异常等)

 新的Thread(){
        公共无效的run(){
            而(ⅰ大于0){
                视频下载(1000);
                mTextView.post(新的Runnable(){
                    公共无效的run(){
                        mTextView.setText(Integer.toString(我 - ));
                    }
                });
            }
        }
    }。开始();

I'm trying to make a simple counter that counts from 5 to 1 and updates the view after every second. I've tried doing it without the handler and just with a simple loop, but it just shows me 1 after waiting or it force closed. I have tried messing with runOnUIThread and threads too, but I'm missing something.

Here's my code:

package com.ammad.test;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.support.v4.app.NavUtils;

public class Main extends Activity {

    TextView tv;
    Button b1;
    Handler mHandler;
    int i = 5;
    private Runnable runnable;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView) findViewById(R.id.tvShow);
        b1 = (Button) findViewById(R.id.bt1);



        runnable = new Runnable() {
            public void run() {
                // do your stuff - don't create a new runnable here!
                tv.setText(String.valueOf(i));
                i--;
                mHandler.postDelayed(runnable, 500);

            }
        };
        b1.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                // TODO Auto-generated method stub
                mHandler.post(runnable);
                mHandler.removeCallbacks(runnable);

            }
        });

    }

    public void doTheLoop() {

        /*
         * runOnUiThread(new Runnable() {
         * 
         * public void run() { for (int i = 5; i >= 1; i--) { // TODO
         * Auto-generated method stub tv.setText(Integer.toString(i)); for (int
         * j = 0; j < 200000; j++) ; } }
         * `enter code here`
         * });
         */
        // mHandler.post(runnable);
    }
}

解决方案

Where are you instantiating mHandler? I think that code is missing, or else this would fail with a NullPointerException. It's important because if you just instantiate it with the no-arg constructor in onCreate it will use the message queue of the UI thread.

There are other issues with this though: inside your Runnable.run method you don't actually check if i is less than zero, so it will always call postDelayed with itself. Furthermore, you're updating the UI (setText) from a non-UI thread, which may cause undefined behavior.

I think your code is just a bit more complicated than it needs to be. If this example is dumbed down to and hides your actual intent, this is an example might be too simple, but here's something that basically works, although you'll need to edit it a bit to compile (catch InterruptedException, etc)

    new Thread() {
        public void run() {
            while(i > 0) {
                Thread.sleep(1000);
                mTextView.post(new Runnable() {
                    public void run() {
                        mTextView.setText(Integer.toString(i--));
                    }
                });
            }
        }
    }.start();

这篇关于更新的TextView使用的处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆