gpt4 book ai didi

android - 使用 while 循环在线程中 sleep ,在 UIThread 中不 sleep

转载 作者:行者123 更新时间:2023-11-30 03:22:14 28 4
gpt4 key购买 nike

如何在不延迟 UIThread 的情况下利用 while 循环中的延迟?我的 while 循环应该在每次应用程序运行循环时更新 UI,但也应该有可能与按钮交互。我当前版本的问题是当 while 循环开始时应用程序暂停,直到 while 循环完成然后更新 UI。我希望它在每次通过时更新 UI。

您有什么想法,也许还有更有效的替代方法吗?

这是我当前的版本:

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Button;
import android.widget.ProgressBar;
import android.view.View.OnClickListener;
import android.widget.Toast;
import java.util.regex.Pattern;


public class ReaderFragment extends Fragment
{

ProgressBar progress_in_main_thread;
private int progressBarStatus = 0;
TextView main_text;
Pattern p = Pattern.compile(" ");
String[] splitted_text;
Button start_button;
Button pause_button;
public boolean paused;
int index = 0;
long wait = 1000;

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
//Layout des Fragments verknuepfen
{
View ReaderFragmentView = inflater.inflate(R.layout.reader_fgmt, container, false);

progress_in_main_thread = (ProgressBar) ReaderFragmentView.findViewById(R.id.reader_progress);
progress_in_main_thread.setProgress(0);
progress_in_main_thread.setVisibility(progress_in_main_thread.VISIBLE);

main_text = (TextView) ReaderFragmentView.findViewById(R.id.center_view);

start_button = (Button) ReaderFragmentView.findViewById(R.id.go);
start_button.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View view)
{
if(InputFragment.text.trim().length() == 0)
{
Toast.makeText(getActivity().getApplicationContext(), "Es wurde kein Text eingegeben!", Toast.LENGTH_SHORT).show();
}
else
{
paused = false;
splitted_text = p.split(InputFragment.text);
progress_in_main_thread.setMax(splitted_text.length-1);

mainThread();
}

}
});

pause_button = (Button) ReaderFragmentView.findViewById(R.id.pause);
pause_button.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View view)
{
paused = true;
}
});




return ReaderFragmentView;
}

private void mainThread()
{
new Thread(new Runnable()
{
@Override
public void run()
{
while(progressBarStatus < (splitted_text.length)-1)
{
progressBarStatus = index;

progress_in_main_thread.setProgress(progressBarStatus);
}
}
}).start();

getActivity().runOnUiThread(new Runnable()
{
public void run()
{

while(!paused)
{
main_text.setText(splitted_text[index]);

if(paused)
{
break;
}
else if(index == (splitted_text.length)-1)
{
Toast.makeText(getActivity().getApplicationContext(), "Ende", Toast.LENGTH_LONG).show();
break;
}
index++;
try
{
Thread.sleep(wait);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}

}

});
}
}

谢谢大家!

最佳答案

根据定义,您不能在不延迟 UI 线程的情况下延迟 UI 线程。

从根本上说,您需要从循环 风格的程序切换到事件 驱动的程序,其中必须处理 Android UI。您的程序不会有 while 循环 - 相反,Android 框架会调用您的代码来执行事件函数,每个事件函数都必须尽快返回。

Android 已经开箱即用地提供用户交互事件,例如触摸和按钮按下,以及生命周期事件。要为 UI 的周期性演变添加事件(您尝试使用 while 循环和延迟执行的操作),您可以创建一个 Timer 并让它的 TimerTask 使用 RunOnUiThread 将一些与 UI 相关的工作推送到 UI 线程上;如果您需要做的事情不涉及 UI,那么您可以在 TimerTask 执行的后台线程中进行。

在您发布的代码中,看起来您可能已经尝试创建自己的后台线程,该线程将运行一个带有 sleep 延迟的循环,并使用 RunOnUiThread 将工作推送到 UI 线程;从技术上讲这是可行的,但与计时器方法相比并不真正受到鼓励。但是,您的操作方式存在两个问题:

  • 首先,您将后台线程的启动器方法命名为 mainThread,这有点令人困惑,因为在 Android 上“主线程”和“UI 线程”是同一个 - 最好调用它 createBackgroundThread() 或其他东西。

  • 其次,在推送到 UI 线程执行的代码中出现 while 和 sleep,这是行不通的。您将需要移动 while 循环并休眠到后台线程中,而当您需要将可以立即完成的小批量工作推送到 UI 线程上时,让它重复使用 RunOnUiThread,例如每个实际的视觉更新。

此外,您可能还需要考虑一下,如果您的实现最终可能会由于重复按下按钮而创建多个并发后台线程,或者您的其中一个线程在发生重要的 Activity Lifecycle 事件时仍在运行。

关于android - 使用 while 循环在线程中 sleep ,在 UIThread 中不 sleep ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18932286/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com