android - Android:Toast 在函数执行后显示,期望它在之前显示
问题描述
可能是一个愚蠢的问题,或者超出了我目前的 Java 知识。无论哪种方式,我都被困住了,所以希望有人可以提供帮助。
我有一个带有菜单和一些项目的应用程序。其中一项用于更新音乐播放列表(该应用程序本质上是 Audacious 的 SSH 遥控器)。由于播放列表更新可能需要一些时间,具体取决于其大小,因此我打算在单击项目时显示一个 toast,并在更新后显示另一个。
问题是,在单击该项目时,主线程挂起(调用一个函数,该函数又调用一个 DoInBackground 函数,并在接收到数据后更新主要活动字段——我无法在后台制作所有内容),并且两个祝酒词显示在最后。所以应用程序似乎被冻结了几秒钟。
菜单代码如下。有没有办法在单击该项目时使该吐司出现?如果需要更多代码,我会发布它。(可能被调用的函数)
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
@SuppressLint("ResourceType")
@Override
public boolean onOptionsItemSelected(MenuItem item) {
final Vibrator vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
switch (item.getItemId()) {
case R.id.Settings:
vib.vibrate(50);
Intent i = new Intent(this, Settings.class);
startActivity(i);
break;
case R.id.Help:
vib.vibrate(50);
HelpWindow();
break;
case R.id.Quit:
vib.vibrate(50);
SshCommands.quit quit = new SshCommands.quit();
quit.execute();
android.os.Process.killProcess(android.os.Process.myPid());
exit(0);
case R.id.refreshPlaylist:
vib.vibrate(50);
if (session != null && session.isConnected()) {
SshCommands.ToastHandler message = new SshCommands.ToastHandler(getApplicationContext());
message.showToast("Downloading playlist. Please wait.");
try {
Thread.sleep(200);
this.refreshPlaylist();
} catch (Exception e) {
e.printStackTrace();
}
} else {
SshCommands.ToastHandler message = new SshCommands.ToastHandler(getApplicationContext());
message.showToast("Not connected.");
}
break;
这是被调用函数的代码:
public void refreshPlaylist() {
if (session != null) {
try {
session.connect();
} catch (Exception e) {
if (e.toString().contains("already connected")) {
SshCommands.getPlaylist getplaylist = new SshCommands.getPlaylist();
SshCommands.loadPlaylist loadplaylist = new SshCommands.loadPlaylist();
try {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
getplaylist.execute();
String currentpl;
while (getplaylist.currentplaylist == null) {
Thread.sleep(500);
}
currentpl = getplaylist.currentplaylist;
playlist.setText("Playlist: " + currentpl);
loadplaylist.execute();
pl = loadplaylist.songs;
while (pl.isEmpty()) {
Thread.sleep(1000);
pl = loadplaylist.songs;
}
createListview();
SshCommands.TrackName song = new SshCommands.TrackName();
song.execute();
o = 0;
int i = 0;
try {
while (i < 30 && song.trackName == null) {
Thread.sleep(100);
i = i + 1;
}
} catch (Exception e1) {
e1.printStackTrace();
}
if (song.trackName != null) {
o = song.trackName;
}
if (!(o == 0)) {
o = o - 1;
scrollToPosition();
} else {
toast();
}
SshCommands.ToastHandler message1 = new SshCommands.ToastHandler(this);
message1.showToast("Playlist downloaded.");
} else {
etc.
//just requests the write permissions on the storage
解决方案
首先,永远不要在主线程上使用 Thread.sleep() 。它会在指定的时间内冻结您的应用程序。最后看到这两个 toast 的原因是它们实际上已发布到应用程序的主线程队列中,该队列被 Thread.sleep() 冻结。
正确的做法是使用 postDelayed()。
推荐阅读
- c# - 以除我的本地帐户以外的任何帐户登录时,Excel 不使用 OPENROWSET 插入数据
- pandas - 在数据帧的非零元素上应用噪声
- django - 如何在我自己的用户表单中创建超级用户?
- wordpress - Wordpress 重定向到错误的主页
- r - R:根据长度选择数据框单元格的快速方法
- sparql - 如何忽略 SPARQL 中的值?
- r - R:通过将其值与其他两列给出的值范围进行比较来更新观察 ID
- laravel - 提交页面后是否必须刷新会话或会话变量?
- couchdb - 无法使用管理员和自签名 SSL 证书复制 CouchDB 数据库
- python - python多处理(ThreadPool)执行时间比顺序执行时间长