当我尝试show();
我的祝酒词时,我遇到了一个奇怪的问题。您将在下面看到两个以try/catch and Thread.sleep();
分隔的Toast。在这种情况下,第二个Toast toast2
将会显示,但toast1
将不显示。
如果我删除try/catch
两个Toasts将显示没有问题。
我在其他地方看到toast.show();
在UI线程上发出请求,这可能会被其他操作冲突。我想知道这是否与我Thread.sleep();
问题有同样的问题我如何解决这个问题?
谢谢
TestService.java
///Debug - Show a Toast
// Toast does NOT show up
Toast toast1 = Toast.makeText(context,"Service Started", Toast.LENGTH_SHORT);
toast1.show();
//Try to sleep for roughly 2 seconds
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Debug - Shows a Toast
Toast toast2 = Toast.makeText(context,"Sleep completed", Toast.LENGTH_SHORT);
toast2.show();
答案 0 :(得分:8)
在现实生活中,你可能会有一些逻辑而不仅仅是“睡觉”,对吗? 正确的android方式,根据您的示例,启动服务将通过在工作线程上执行它。这将确保您不会得到ANR。
你的看起来像是:
new AsyncTask<Void, Void, Void>() {
@Override
protected void onPostExecute(Void result) {
Toast toast2 = Toast.makeText(context, "Sleep completed",
Toast.LENGTH_SHORT);
toast2.show();
}
@Override
protected void onPreExecute() {
Toast toast1 = Toast.makeText(context, "Service Started",
Toast.LENGTH_SHORT);
toast1.show();
}
@Override
protected Void doInBackground(Void... params) {
// Try to sleep for roughly 2 seconds
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}.execute();
答案 1 :(得分:1)
由于您在第一次吐司后立即暂停ui线程,因此不会 有机会被展示。到睡眠结束时,首先是时间 吐司已经过去了。
这听起来似乎是最合理的解释,但我可能错了。需要深入挖掘Android 代码,以确定。
答案 2 :(得分:0)
我假设您需要创建一个持续时间超过2秒的Toast(为什么在发送另一个Toast之前应该使用Thread.Sleep(2000)
?)。
所以我刚发现this link提供了一个非常好的例子
希望这有帮助
答案 3 :(得分:0)
我遇到了同样的问题,我将按照建议使用AsyncTask尝试解决,但我的用例如下:
1)我想显示Toast消息(开始广播消息) 2)如果条件合适,我向客户广播message1。 3)我睡2秒钟以完成广播。 4)我一直向客户广播message2。 5)如果它完成了,我会Toast另一条消息(广播消息已完成)
我已经提出了以下解决方案示例(尽管toast消息的序列仍然反向显示):
package com.toasttester;
import android.os.Handler;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import android.os.AsyncTask;
public class MainActivity extends ActionBarActivity {
Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PreSleepToast pst = new PreSleepToast();
pst.execute();
Toast t = Toast.makeText(getApplicationContext(), "Message1", Toast.LENGTH_SHORT);
t.show();
try {
Thread.sleep(2000);//to allow broadcasting to complete
} catch (Exception e) {
e.printStackTrace();
}
callToast1();
}
private Runnable r = new Runnable() {
@Override
public void run() {
Toast t = Toast.makeText(getApplicationContext(), "Message3", Toast.LENGTH_SHORT);
t.show();
}
};
public class PreSleepToast extends AsyncTask<Void, byte[], Void> {
/**
* The sender socket on which we send connections.
*/
public PreSleepToast() {
}
/**
* Polling loop for outgoing connections.
*/
@Override
protected Void doInBackground(Void... params) {
handler.post(r);
return null;
};
};
public void callToast1(){
Toast t = Toast.makeText(getApplicationContext(), "Message2", Toast.LENGTH_SHORT);
t.show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}