我该如何修复这个 CalledFromWrongThreadException?
how can i Fix this CalledFromWrongThreadException?
so i am trying to learn the android web services and when i run my
code i get this Exception can you :
FATAL EXCEPTION: Thread-4
Process: com.example.abdallahmurad.webservices_test, PID: 7328
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6855)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1040)
at android.view.View.requestLayout(View.java:19654)
at android.view.View.requestLayout(View.java:19654)
at android.view.View.requestLayout(View.java:19654)
at android.view.View.requestLayout(View.java:19654)
at android.view.View.requestLayout(View.java:19654)
at android.view.View.requestLayout(View.java:19654)
at android.view.View.requestLayout(View.java:19654)
at android.support.constraint.ConstraintLayout.requestLayout(ConstraintLayout.java:884)
at android.view.View.requestLayout(View.java:19654)
at android.widget.TextView.checkForRelayout(TextView.java:7363)
at android.widget.TextView.setText(TextView.java:4475)
at android.widget.TextView.setText(TextView.java:4332)
at android.widget.TextView.setText(TextView.java:4307)
at com.example.abdallahmurad.webservices_test.MainActivity.run(MainActivity.java:52)
at java.lang.Thread.run(Thread.java:761)
这里是 MainActivity 代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ButterKnife.bind(this);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
URL dataPath = new URL("http://abdallahmurad.hostkda.com/myfirst_echo_test.php");
HttpURLConnection myFirstConnection = (HttpURLConnection) dataPath.openConnection();
InputStreamReader inputStreamReader = new InputStreamReader(myFirstConnection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String data = bufferedReader.readLine();
textView.setText(data);
System.out.println(data);
Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
});
}
myfirst_echo_test.php 是一个简单的 php 文件,只有一个 echo""
我的问题是这个异常是什么,我该如何解决它?
您只能从主线程
更新 ui
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(data);
}
});
textView.setText(data);
导致此问题的原因是您试图在非 ui 线程中设置 UI 元素的文本。您应该更改代码并通过调用 RunOnUiThread
:
在 ui 线程中执行
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(data);
Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
}
});
如果您尝试在非 ui 线程(例如您的 Runnable)中操作任何 UI 元素(不仅是 textView),这总是会发生。作为 Runnable 的替代方案,您还可以尝试 AsyncTask
执行您的操作并操作 onPostExecute()
.
中的 UI 元素
new AsyncTask<Void,Void,Void>(){
String data="";
@Override
protected Void doInBackground(Void... params) {
URL dataPath = new URL("http://abdallahmurad.hostkda.com/myfirst_echo_test.php");
HttpURLConnection myFirstConnection = (HttpURLConnection) dataPath.openConnection();
InputStreamReader inputStreamReader = new InputStreamReader(myFirstConnection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
data = bufferedReader.readLine();
return null;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
textView.setText(data);
Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
}
}.execute();
请记住,还必须在 OnPostExecute
中调用 toast。
so i am trying to learn the android web services and when i run my code i get this Exception can you :
FATAL EXCEPTION: Thread-4
Process: com.example.abdallahmurad.webservices_test, PID: 7328
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6855)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1040)
at android.view.View.requestLayout(View.java:19654)
at android.view.View.requestLayout(View.java:19654)
at android.view.View.requestLayout(View.java:19654)
at android.view.View.requestLayout(View.java:19654)
at android.view.View.requestLayout(View.java:19654)
at android.view.View.requestLayout(View.java:19654)
at android.view.View.requestLayout(View.java:19654)
at android.support.constraint.ConstraintLayout.requestLayout(ConstraintLayout.java:884)
at android.view.View.requestLayout(View.java:19654)
at android.widget.TextView.checkForRelayout(TextView.java:7363)
at android.widget.TextView.setText(TextView.java:4475)
at android.widget.TextView.setText(TextView.java:4332)
at android.widget.TextView.setText(TextView.java:4307)
at com.example.abdallahmurad.webservices_test.MainActivity.run(MainActivity.java:52)
at java.lang.Thread.run(Thread.java:761)
这里是 MainActivity 代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ButterKnife.bind(this);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
URL dataPath = new URL("http://abdallahmurad.hostkda.com/myfirst_echo_test.php");
HttpURLConnection myFirstConnection = (HttpURLConnection) dataPath.openConnection();
InputStreamReader inputStreamReader = new InputStreamReader(myFirstConnection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String data = bufferedReader.readLine();
textView.setText(data);
System.out.println(data);
Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
});
}
myfirst_echo_test.php 是一个简单的 php 文件,只有一个 echo""
我的问题是这个异常是什么,我该如何解决它?
您只能从主线程
更新 uiMainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(data);
}
});
textView.setText(data);
导致此问题的原因是您试图在非 ui 线程中设置 UI 元素的文本。您应该更改代码并通过调用 RunOnUiThread
:
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(data);
Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
}
});
如果您尝试在非 ui 线程(例如您的 Runnable)中操作任何 UI 元素(不仅是 textView),这总是会发生。作为 Runnable 的替代方案,您还可以尝试 AsyncTask
执行您的操作并操作 onPostExecute()
.
new AsyncTask<Void,Void,Void>(){
String data="";
@Override
protected Void doInBackground(Void... params) {
URL dataPath = new URL("http://abdallahmurad.hostkda.com/myfirst_echo_test.php");
HttpURLConnection myFirstConnection = (HttpURLConnection) dataPath.openConnection();
InputStreamReader inputStreamReader = new InputStreamReader(myFirstConnection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
data = bufferedReader.readLine();
return null;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
textView.setText(data);
Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
}
}.execute();
请记住,还必须在 OnPostExecute
中调用 toast。