- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经创建了一个可以从 Activity 中的任何地方访问的 Handler
,并且还编写了一个方法来更轻松地调用处理程序:
private Handler textFromBGThread = new Handler() {
@Override
public void handleMessage (Message msg) {
// Get the string from the msg
String outputString = msg.getData().getString("Output");
// Find the TextView
TextView Output = (TextView)findViewById(R.id.ConsoleOutputView);
// Display the output
Log.i("TextOutput","About to display message: " + outputString);
Output.setText(Output.getText() + outputString);
Log.i("TextOutput","Message displayed");
}
};
private void TextOutputWrapper (String outputText) {
Message msg = new Message();
Bundle bndle = new Bundle();
bndle.putString("Output", "\n" + outputText);
msg.setData(bndle);
textFromBGThread.handleMessage(msg);
}
那么这可以从后台线程简单地调用:
TextOutputWrapper("Attemping to connect...");
这将工作 1 次以上,但是,实际的视觉变化将导致抛出 CalledFromWrongThreadException
。作为 Java 和 Android 的新手,我很困惑为什么会这样。
我注意到,当调用之间的时间间隔稍长时,崩溃往往会发生,并且如果对 TextOutputWrapper(String)
的调用接连发生得非常快,那么它就会起作用。例如,这个:
int i = 0;
while (i < 200) {
TextOutputWrapper(String.valueOf(i));
i++;
}
工作正常。
查看 LogCat 后,垃圾收集器似乎释放了一些资源,然后在下次调用 TextOutputWrapper(String)
时崩溃(当 Output.SetText(String)
被调用,准确地说),尽管我不确定为什么会导致此错误。
最佳答案
这里有一些我要更改的地方:
Handler
如果您想触发 UI 更新并从非 UI 线程(又名)执行此操作,则很有用背景”线程)。
在您的情况下,它不符合该目的。您正在直接调用
textFromBGThread.handleMessage(msg);
它不是为您设计的。您应该使用 Handler
的方式是在 handleMessage(Message)
方法中实现您想要对 UI 执行的操作。你做到了。但是,您不应该直接调用handleMessage()
。如果您这样做,那么 handleMessage()
将从调用 TextOutputWrapper()
的任何线程调用。 如果那是后台线程,那就错了。
您要做的是调用处理程序的 sendMessage(Message)方法(或其他可用变体之一)。 sendMessage()
会将您的消息放入线程安全的队列中,然后在主线程上进行处理。然后主线程将调用您的处理程序的 handleMessage()
,将其传回排队的消息,并允许它安全地更改 UI。因此,更改 TextOutputWrapper()
以使用它:
private void TextOutputWrapper (String outputText) {
Message msg = new Message();
Bundle bndle = new Bundle();
bndle.putString("Output", "\n" + outputText);
msg.setData(bndle);
textFromBGThread.sendMessage(msg);
}
对于有经验的 Java 开发人员来说,这段代码有点难读。在 Java 中,typical coding standards为类之类的东西保留大写名称,而方法以小写字母开头。因此,请将该方法重命名为:
private void textOutputWrapper (String outputText);
或者,更好的是,因为这实际上是一个方法,而不是包装器,本身,重命名为类似
private void outputText(String text);
最后,如果您只是想要一种允许您从任何线程安全地修改 UI 的方法,我可能会建议您使用另一种技术。我发现 Handler
对初学者来说不是那么容易使用。
private void outputText(final String outputString) {
runOnUiThread(new Runnable() {
@Override
public void run() {
// Find the TextView
TextView output = (TextView)findViewById(R.id.ConsoleOutputView);
// Display the output
Log.i("TextOutput","About to display message: " + outputString);
output.setText(Output.getText() + outputString);
Log.i("TextOutput","Message displayed");
}
});
}
runOnUiThread()
是每个 Activity
中可用的方法。
我还将向您指出一些有关了解 Android 中线程的一般文档:
http://www.vogella.com/articles/AndroidBackgroundProcessing/article.html
http://android-developers.blogspot.com/2009/05/painless-threading.html
关于java - 处理程序更改 UI 导致 CalledFromWrongThreadException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16513948/
我已经看到很多关于这个主题的问题,但我对任何答案都不满意。 我希望它有一个 class ConnectionController implements Runnable 负责打开到服务器的连接,读取和
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setCon
当我按下按钮时,我不断收到 CalledFromWringThreadException。 我的程序是这样的: public class MainActivity extends Activity i
我正在创建一款使用 Sphero 机器人球的游戏。当游戏开始/恢复时,它会检查配对或连接的球。如果蓝牙关闭,或者没有配对球,它会隐藏连接窗口。如果有配对但未连接的球,则转到此功能。 // If the
我们从 Crashlytics 收到错误报告,影响了相当一部分用户(大约 10%)。这是一个 CalledFromWrongThreadException。 问题是我不知道是什么导致了这个问题,我自己
我有一个 Activity 启动然后创建一个新的 NetworkHandler 实例,在 NetworkHandler 中我在一个新线程上运行它,这样 UI 线程就不会被卡住。 NetworkHand
我在 ListView 中显示了网页下载百分比的进度条。 for(int i=0;i { int id; public UploadTask(int id) {
我有一个 IntentService 可以像这样更新偏好: SharedPreferences.Editor editor = userPrefs.edit(); editor.putInt("COU
我正在尝试使用 Kotlin 协程在后台运行一些繁重的工作。 但是我收到了这个错误信息, 'android.view.ViewRootImpl$CalledFromWrongThreadExcepti
我有一种感觉是我的计时器导致了这次崩溃。奇怪的是我似乎无法在模拟器中重现它,但我的 Play 控制台崩溃报告告诉我用户不断遇到此崩溃: android.view.ViewRootImpl$Called
我使用的是 this , 显示来自互联网的图像,但它会引发如下错误: 04-12 13:45:05.337: E/AndroidRuntime(27897): Caused by: android.v
我的 logcat 中出现错误,指出: java.net.UnknownHostException: apps.example.com 09-13 14:57:28.970: W/System.err
我是 Android 初学者,所以如果这是一个愚蠢的问题,请友善。 我正在尝试动态更新四个 TextView。每当我尝试更新它们时,程序就会崩溃。 我不明白“只有创建 View 层次结构的原始线程才能
我在编写的应用程序中遇到一个非常奇怪的问题。这可能很简单,我对服务、AsyncTasks 以及何时可以再次访问 UI 线程有一些误解。 该应用程序包含一个主要 Activity ,您可以通过该 Act
我正在按照 android 教程构建天气应用程序,但是当我尝试将 mTemperature TextView 设置为我从预测 API 获得的温度时,我收到此错误“android.view.ViewRo
我在做 Espresso 测试时出错 android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original threa
我已经创建了一个可以从 Activity 中的任何地方访问的 Handler,并且还编写了一个方法来更轻松地调用处理程序: private Handler textFromBGThread = new
我正在为一个 Android 应用开发一个测试类,我收到了一个 android.view.ViewRootImpl$CalledFromWrongThreadException。该代码假设模拟输入到文
我正在使用 OpenCV 库实现一个应用程序。处理完相机的 inputFrame 后,我想更新我的 TextView。但是,我收到以下错误: 08-01 17:01:45.085: E/Android
我不确定我的低估是否正确,因为我没有得到预期的输出。我有一个类,我在其中调用一个应该启动线程的方法。 public class MainActivity extends Activity { prot
我是一名优秀的程序员,十分优秀!