Android - 非 UI 线程使我的 UI 无响应
Android - non UI Thread rendering my UI unresponsive
当我在 activity 中调用此线程时,它会使 UI 无响应,因此一旦它启动我就无法执行任何操作。我认为它与 I/O 流有关,但我不确定如何解决该问题。任何帮助将不胜感激,但我是 Android 和线程的新手,所以我可能有一些后续问题。
这是我的话题:
mHandler = new Handler();
new Thread(new Runnable() {
@Override
public void run () {
mHandler.post(new Runnable() {
@Override
public void run () {
int counter = 0;
while (true) {
counter++;
try {
output = "";
if (mInStream != null) {
mInStream.read(buffer);
for (byte b : buffer) {
char c = (char) b;
if (c >= ' ' && c < 'z') {
//System.out.print(c);
output += c;
}
}
//System.out.println();
Intent intent = new Intent();
intent.setAction("com.curie.WEIGHT_RECEIVED");
intent.putExtra("Output",output);
if (counter % 10 == 0) {
System.out.println(counter);
LocalBroadcastManager.getInstance(InputActivity.getContext()).sendBroadcastSync(intent);
}
}
// Send the obtained bytes to the UI Activity
} catch (IOException e) {
//an exception here marks connection loss
//send message to UI Activity
break;
}
}
}
});
}
}).start();
编辑:答案确实解决了我的问题,但我现在收到此错误。
当我调用 inputwindow.setText(weight)
时会发生此错误,它将 TextView 中的文本设置为从线程广播的值。
E/AndroidRuntime: FATAL EXCEPTION: Thread-2358
Process: com.example.curie.fairbanks_03, PID: 15718
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:8358)
at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1364)
at android.view.ViewGroup.invalidateChild(ViewGroup.java:5433)
at android.view.View.invalidateInternal(View.java:13997)
at android.view.View.invalidate(View.java:13961)
at android.view.View.invalidate(View.java:13945)
at android.widget.TextView.checkForRelayout(TextView.java:8403)
at android.widget.TextView.setText(TextView.java:5011)
at android.widget.TextView.setText(TextView.java:4836)
at android.widget.TextView.setText(TextView.java:4811)
at com.example.curie.fairbanks_03.InputActivity.onReceive(InputActivity.java:67)
at android.support.v4.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:311)
at android.support.v4.content.LocalBroadcastManager.sendBroadcastSync(LocalBroadcastManager.java:289)
at com.example.curie.fairbanks_03.BluetoothConnection.run(BluetoothConnection.java:176)
at java.lang.Thread.run(Thread.java:818)
它使您的 UI 无响应,因为它正在 运行宁 在 UI 线程 中!您启动了一个新线程来执行 运行 任务,但随后在该线程中调用了 mHandler.post
,它返回到创建 mHandler
的线程,即 UI 线。没有理由这样做。只需在您创建的线程中执行操作,而无需调用处理程序。
new Thread(new Runnable() {
@Override
public void run () {
int counter = 0;
while (true) {
counter++;
try {
output = "";
if (mInStream != null) {
mInStream.read(buffer);
for (byte b : buffer) {
char c = (char) b;
if (c >= ' ' && c < 'z') {
//System.out.print(c);
output += c;
}
}
//System.out.println();
Intent intent = new Intent();
intent.setAction("com.curie.WEIGHT_RECEIVED");
intent.putExtra("Output",output);
if (counter % 10 == 0) {
System.out.println(counter);
LocalBroadcastManager.getInstance(InputActivity.getContext()).sendBroadcastSync(intent);
}
}
// Send the obtained bytes to the UI Activity
} catch (IOException e) {
//an exception here marks connection loss
//send message to UI Activity
break;
}
}
}
}).start();
当我在 activity 中调用此线程时,它会使 UI 无响应,因此一旦它启动我就无法执行任何操作。我认为它与 I/O 流有关,但我不确定如何解决该问题。任何帮助将不胜感激,但我是 Android 和线程的新手,所以我可能有一些后续问题。
这是我的话题:
mHandler = new Handler();
new Thread(new Runnable() {
@Override
public void run () {
mHandler.post(new Runnable() {
@Override
public void run () {
int counter = 0;
while (true) {
counter++;
try {
output = "";
if (mInStream != null) {
mInStream.read(buffer);
for (byte b : buffer) {
char c = (char) b;
if (c >= ' ' && c < 'z') {
//System.out.print(c);
output += c;
}
}
//System.out.println();
Intent intent = new Intent();
intent.setAction("com.curie.WEIGHT_RECEIVED");
intent.putExtra("Output",output);
if (counter % 10 == 0) {
System.out.println(counter);
LocalBroadcastManager.getInstance(InputActivity.getContext()).sendBroadcastSync(intent);
}
}
// Send the obtained bytes to the UI Activity
} catch (IOException e) {
//an exception here marks connection loss
//send message to UI Activity
break;
}
}
}
});
}
}).start();
编辑:答案确实解决了我的问题,但我现在收到此错误。
当我调用 inputwindow.setText(weight)
时会发生此错误,它将 TextView 中的文本设置为从线程广播的值。
E/AndroidRuntime: FATAL EXCEPTION: Thread-2358
Process: com.example.curie.fairbanks_03, PID: 15718
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:8358)
at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1364)
at android.view.ViewGroup.invalidateChild(ViewGroup.java:5433)
at android.view.View.invalidateInternal(View.java:13997)
at android.view.View.invalidate(View.java:13961)
at android.view.View.invalidate(View.java:13945)
at android.widget.TextView.checkForRelayout(TextView.java:8403)
at android.widget.TextView.setText(TextView.java:5011)
at android.widget.TextView.setText(TextView.java:4836)
at android.widget.TextView.setText(TextView.java:4811)
at com.example.curie.fairbanks_03.InputActivity.onReceive(InputActivity.java:67)
at android.support.v4.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:311)
at android.support.v4.content.LocalBroadcastManager.sendBroadcastSync(LocalBroadcastManager.java:289)
at com.example.curie.fairbanks_03.BluetoothConnection.run(BluetoothConnection.java:176)
at java.lang.Thread.run(Thread.java:818)
它使您的 UI 无响应,因为它正在 运行宁 在 UI 线程 中!您启动了一个新线程来执行 运行 任务,但随后在该线程中调用了 mHandler.post
,它返回到创建 mHandler
的线程,即 UI 线。没有理由这样做。只需在您创建的线程中执行操作,而无需调用处理程序。
new Thread(new Runnable() {
@Override
public void run () {
int counter = 0;
while (true) {
counter++;
try {
output = "";
if (mInStream != null) {
mInStream.read(buffer);
for (byte b : buffer) {
char c = (char) b;
if (c >= ' ' && c < 'z') {
//System.out.print(c);
output += c;
}
}
//System.out.println();
Intent intent = new Intent();
intent.setAction("com.curie.WEIGHT_RECEIVED");
intent.putExtra("Output",output);
if (counter % 10 == 0) {
System.out.println(counter);
LocalBroadcastManager.getInstance(InputActivity.getContext()).sendBroadcastSync(intent);
}
}
// Send the obtained bytes to the UI Activity
} catch (IOException e) {
//an exception here marks connection loss
//send message to UI Activity
break;
}
}
}
}).start();