可能是一个愚蠢的问题,或者超出了我目前的Java知识。无论哪种方式,我都受困于此,希望有人可以提供帮助。
我有一个带有菜单和一些项目的应用程序。这些项目之一旨在更新音乐播放列表(该应用程序实质上是Audacious的SSH遥控器)。由于播放列表更新可能需要一段时间,具体取决于它的大小,因此我打算在单击项目时显示祝酒词,在更新项目后再显示祝酒词。
问题是,在单击该项目时,主线程挂起(调用一个函数,该函数又调用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()。它将冻结您的应用程序指定的时间。您最终看到这两个祝酒的原因是它们实际上已发布到应用程序的主线程队列中,并由Thread.sleep()冻结。
正确的方法是使用postDelayed()。