gpt4 book ai didi

java - 在 AsyncTask 中运行 CountDownTimer 会抛出 java.lang.RuntimeException - Looper.prepare()

转载 作者:行者123 更新时间:2023-11-29 23:28:27 25 4
gpt4 key购买 nike

我有一个 .lrc 文件,我需要用 CountDownTimer 遍历每一行。我已尝试使用 AsyncTask 来执行此操作,但出现错误:

Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

在线 new CountDownTimer... 我试着用 runnable 来做,但我仍然得到同样的错误。我的目标是让它遍历 .lrc 文件中的每一行,如下所示:

[00:04.15]Help me, it's like the walls are caving in
[00:10.46]Sometimes I feel like giving up
[00:13.63]But I just can't
...

我不确定按照我尝试的方式进行操作的效率如何。我正在考虑遍历 doInBackground() 中的每一行。如果有更好的方法,请告诉我。但首先,为什么我会得到 EXCEPTION

请注意..我已经尽可能地简化了代码,以便更容易理解我正在尝试做的事情。

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

MyView myView = new
myView.play();
}
}

public class MyView{

public void play() {
new CustomAsync().execute();
}
}

class CustomAsync extends AsyncTask<Lyric, Void, Void> {

protected Void doInBackground(Lyric... param) {
startLyricCountDownTimer(param);
return null;
}

protected void onPostExecute(Void param) {
//Print Toast or open dialog
}

private void startLyricCountDownTimer(Lyric lyric){

new CountDownTimer(30000, 10) { //This is where it throws the error

public void onTick(long millisUntilFinished) {
//Do the thing
}
public void onFinish() {

}
}.start();
}
}

编辑是使用 AsyncTask 并像 Son Truong 建议的那样更好,还是对每一行 lrc 使用以下代码?

new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
new CountDownTimer(millisInFuture,countDownInterval) {
@Override
public void onTick(

最佳答案

CountDownTimer 使用 Handler 将消息发布到具有 Looper 的线程的消息队列。 onTickonFinish 将根据您创建 CountDownTimer 实例的位置在哪个线程上调用。

在您的情况下,因为您在 AsyncTask 的 doInBackground 方法中创建了 CountDownTimer 实例,所以这两个方法将在 AsyncTask 线程上调用。

在 CountDownTimer 的构造函数中,它也会创建 Handler 实例。 Handler 会检查当前线程是否有 Looper,如果没有,它会抛出一个 RuntimeException 和消息。

Can't create handler inside thread that has not called Looper.prepare()

因为 AsyncTask 使用没有 Looper 的线程,这就是您的应用程序崩溃的原因。

我的建议是在 doInBackground 方法中打开一个到 .lrc 文件的连接并读取每一行,对于读取的每一行,使用 runOnUIThread 将行发送到 UI 线程(然后您可以通过在屏幕上显示 Toast 等来处理那里读取的行)。

更新:我将演示如何从文件中逐行读取,然后每 3 秒将其显示在 TextView 中。

首先编写一个逐行读取输入流的类

static class ReadLyricTask extends AsyncTask<InputStream, String, Void> {

WeakReference<MainActivity> mMainActivity;

ReadLyricTask(MainActivity activity) {
mMainActivity = new WeakReference<>(activity);
}

@Override
protected Void doInBackground(InputStream... inputStreams) {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStreams[0]));
String line;
try {
while ((line = reader.readLine()) != null) {
publishProgress(line);
}
} catch (IOException e) {
// Do nothing.
} finally {
try {
inputStreams[0].close();
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}

@Override
protected void onProgressUpdate(String... values) {
MainActivity activity = mMainActivity.get();
if (activity != null) {
activity.displayLyricLineOnTextView(values[0]);
}
}
}

然后在MainActivity中使用就可以了

public class MainActivity extends AppCompatActivity {
private static final int UPDATE_LYRIC_TEXT_INTERVAL = 3000; // Change lyric text each 3 seconds.
private int mCurrentInterval = 0;

private TextView mLyricTextView;

private Handler mHandler = new Handler();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLyricTextView = findViewById(R.id.lyricText);

// I put a file named lyric.lrc in raw folder, for your case just open an input stream from a file.
InputStream inputStream = getResources().openRawResource(R.raw.lyric);
new ReadLyricTask(this).execute(inputStream);
}

private void displayLyricLineOnTextView(final String lyricLine) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mLyricTextView.setText(lyricLine);
}
}, mCurrentInterval);

mCurrentInterval += UPDATE_LYRIC_TEXT_INTERVAL;
}
}

关于java - 在 AsyncTask 中运行 CountDownTimer 会抛出 java.lang.RuntimeException - Looper.prepare(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53122598/

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