如何在定时器内显示toast?

发布于 2024-10-20 16:07:59 字数 680 浏览 3 评论 0原文

我想在计时器内显示 toast 消息,我使用了以下代码:

timer.scheduleAtFixedRate( new TimerTask()
{       
public void run()
{
    try {  
        fun1();
        } catch (Exception e) {e.printStackTrace(); }            
    }   
}, 0,60000);    

public void fun1()
{
    //want to display toast
}

并且出现以下错误:

WARN/System.err(593): java.lang.RuntimeException: 无法在未调用 Looper.prepare() 的线程内创建处理程序

警告/System.err(593):位于 android.os.Handler.(Handler.java:121)

警告/System.err(593):位于 android.widget.Toast.(Toast.java:68)

警告/System.err(593):位于 android.widget.Toast.makeText(Toast.java:231)

谢谢。

I want to display toast message inside timer and I used the following code :

timer.scheduleAtFixedRate( new TimerTask()
{       
public void run()
{
    try {  
        fun1();
        } catch (Exception e) {e.printStackTrace(); }            
    }   
}, 0,60000);    

public void fun1()
{
    //want to display toast
}

And I am getting following error:

WARN/System.err(593): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

WARN/System.err(593): at android.os.Handler.(Handler.java:121)

WARN/System.err(593): at android.widget.Toast.(Toast.java:68)

WARN/System.err(593): at android.widget.Toast.makeText(Toast.java:231)

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

人事已非 2024-10-27 16:07:59

您无法在单独的线程内进行 UI 更新,例如计时器。您应该使用 Handler 对象进行 UI 更新:

timer.scheduleAtFixedRate( new TimerTask() {
private Handler updateUI = new Handler(){
@Override
public void dispatchMessage(Message msg) {
    super.dispatchMessage(msg);
    fun1();
}
};
public void run() { 
try {
updateUI.sendEmptyMessage(0);
} catch (Exception e) {e.printStackTrace(); }
}
}, 0,60000);

You can't make UI updates inside separate Thread, like Timer. You should use Handler object for UI update:

timer.scheduleAtFixedRate( new TimerTask() {
private Handler updateUI = new Handler(){
@Override
public void dispatchMessage(Message msg) {
    super.dispatchMessage(msg);
    fun1();
}
};
public void run() { 
try {
updateUI.sendEmptyMessage(0);
} catch (Exception e) {e.printStackTrace(); }
}
}, 0,60000);
绾颜 2024-10-27 16:07:59

最简单的方法(IMO)是:

new Timer().scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        final String message = "Hi";
        MyActivity.this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MyActivity.this, message, Toast.LENGTH_SHORT).show();
            }
        });
    }
});

关键是 MyActivity.this.runOnUiThread(Runnable)。

The easiest way (IMO) is:

new Timer().scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        final String message = "Hi";
        MyActivity.this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MyActivity.this, message, Toast.LENGTH_SHORT).show();
            }
        });
    }
});

The key being MyActivity.this.runOnUiThread(Runnable).

一身软味 2024-10-27 16:07:59

创建一个 Handler 并在其中显示 toast

private Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            // Toast here
        }
    };

create a Handler and display toast in this

private Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            // Toast here
        }
    };
提笔落墨 2024-10-27 16:07:59

您需要访问应用程序的上下文才能执行此操作。尝试创建您自己的类,它将上下文作为输入参数:

private class MyTimerTask extends TimerTask {
    private Context context;
    public MyTimerTask(Context context) {
        this.context = context;
    }

    @Override
    public void run() {
        Toast.makeText(context, "Toast text", Toast.LENGTH_SHORT).show();
    }

}

然后在您的计时器中:

timer.scheduleAtFixedRate( new MyTimerTask(this), 0,60000);

You need access to the Context of the application to be able to do this. Try creating your own class which takes the context as input parameter:

private class MyTimerTask extends TimerTask {
    private Context context;
    public MyTimerTask(Context context) {
        this.context = context;
    }

    @Override
    public void run() {
        Toast.makeText(context, "Toast text", Toast.LENGTH_SHORT).show();
    }

}

Then in your timer:

timer.scheduleAtFixedRate( new MyTimerTask(this), 0,60000);
娇柔作态 2024-10-27 16:07:59

我想做一个简单的项目,可以在计时器中显示 Toast。
计时器将使用服务启动。然后,定时器在服务启动时启动,在服务停止时停止。

1 级

package com.example.connect;


import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {

Button button1,button2;
 private Handler mHandler = new Handler();

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    button1=(Button)findViewById(R.id.button1);
    button2=(Button)findViewById(R.id.button2);


}


public void Start(View v)
{
    startService(new Intent(MainActivity.this , Connect_service.class));

}

public void Stop(View v)
{
    stopService(new Intent(MainActivity.this , Connect_service.class));

}

}

2 级

package com.example.connect;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;

public class Connect_service extends Service{

Timer timer = new Timer();
TimerTask updateProfile = new CustomTimerTask(Connect_service.this);

public void onCreate() {

    super.onCreate();

    Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
    timer.scheduleAtFixedRate(updateProfile, 0, 5000);

}


@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    Toast.makeText(this, "Service Stopped", Toast.LENGTH_SHORT).show();
    timer.cancel();
}



@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}

}

3 级

package com.example.connect;

import java.util.TimerTask;

import android.content.Context;
import android.os.Handler;
import android.widget.Toast;
public class CustomTimerTask extends TimerTask {


private Context context;
private Handler mHandler = new Handler();

public CustomTimerTask(Context con) {
    this.context = con;
}



@Override
public void run() {
    new Thread(new Runnable() {

        public void run() {

            mHandler.post(new Runnable() {
                public void run() {
                   Toast.makeText(context, "In Timer", Toast.LENGTH_SHORT).show();

                }
            });
        }
    }).start();

}

}

I wanted to make a simple project that could display a Toast in a Timer.
The Timer would be started using a service. Then, the Timer starts when the service is started and stops when service is stopped.

Class 1

package com.example.connect;


import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {

Button button1,button2;
 private Handler mHandler = new Handler();

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    button1=(Button)findViewById(R.id.button1);
    button2=(Button)findViewById(R.id.button2);


}


public void Start(View v)
{
    startService(new Intent(MainActivity.this , Connect_service.class));

}

public void Stop(View v)
{
    stopService(new Intent(MainActivity.this , Connect_service.class));

}

}

Class 2

package com.example.connect;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;

public class Connect_service extends Service{

Timer timer = new Timer();
TimerTask updateProfile = new CustomTimerTask(Connect_service.this);

public void onCreate() {

    super.onCreate();

    Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
    timer.scheduleAtFixedRate(updateProfile, 0, 5000);

}


@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    Toast.makeText(this, "Service Stopped", Toast.LENGTH_SHORT).show();
    timer.cancel();
}



@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}

}

Class 3

package com.example.connect;

import java.util.TimerTask;

import android.content.Context;
import android.os.Handler;
import android.widget.Toast;
public class CustomTimerTask extends TimerTask {


private Context context;
private Handler mHandler = new Handler();

public CustomTimerTask(Context con) {
    this.context = con;
}



@Override
public void run() {
    new Thread(new Runnable() {

        public void run() {

            mHandler.post(new Runnable() {
                public void run() {
                   Toast.makeText(context, "In Timer", Toast.LENGTH_SHORT).show();

                }
            });
        }
    }).start();

}

}
写下不归期 2024-10-27 16:07:59

我正在尝试用我自己的观点来祝酒。

我已经成功地结合了你们的方法。以下代码允许我显示 toast 并更改/删除视图而不会崩溃,只需将 MyTimerTask 构造函数的参数更改为您需要处理的任何内容即可。

public void yourFunction(){

    Timer timer = new Timer();
    MyTimerTask mtc = new MyTimerTask(this.getContext(), tvNotice);
    timer.schedule(mtc, 1000);
}

private class MyTimerTask extends TimerTask {

    private TextView tv;
    private Context context;
    public MyTimerTask(Context pContext, TextView pTv) {
        this.tv = pTv;
        this.context = pContext;
    }
    @Override
    public void run() {
        updateUI.sendEmptyMessage(0);
    }

    private Handler updateUI = new Handler(){
        @Override
        public void dispatchMessage(Message msg) {
            super.dispatchMessage(msg);


            tv.setText("TextView Message");
            Toast.makeText(context, "Toast Message", 0).show();
        }
    };
}

I'm trying to make my own toast with my own views.

I've successfully combined your approaches. The following code allows me to show toasts and change/remove views without crashing, just change the parameters of the MyTimerTask constructor to whatever you need to work on.

public void yourFunction(){

    Timer timer = new Timer();
    MyTimerTask mtc = new MyTimerTask(this.getContext(), tvNotice);
    timer.schedule(mtc, 1000);
}

private class MyTimerTask extends TimerTask {

    private TextView tv;
    private Context context;
    public MyTimerTask(Context pContext, TextView pTv) {
        this.tv = pTv;
        this.context = pContext;
    }
    @Override
    public void run() {
        updateUI.sendEmptyMessage(0);
    }

    private Handler updateUI = new Handler(){
        @Override
        public void dispatchMessage(Message msg) {
            super.dispatchMessage(msg);


            tv.setText("TextView Message");
            Toast.makeText(context, "Toast Message", 0).show();
        }
    };
}
毁我热情 2024-10-27 16:07:59

您必须调用 UIThread 来显示 Toast,而不是从计时器线程调用。

否则从该计时器线程调用 UI 线程。

此链接将为您提供帮助,

http://developer.android.com/ resources/articles/timed-ui-updates.html

和这个

http://developer.android.com/guide/appendix/faq/commontasks.html#threading

You have to call UIThread for showing Toast, not from timer thread.

Else call UI thread from that timer thread.

This link will help you,

http://developer.android.com/resources/articles/timed-ui-updates.html

and this

http://developer.android.com/guide/appendix/faq/commontasks.html#threading

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文