必须从 UI 线程(Android Studio)调用方法 getText()
Method getText() must be called from the UI Thread (Android Studio)
我正在尝试为应用程序创建登录名。但是我有一个问题。
这是我的代码:
package com.forgetmenot.loginregister;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends Activity {
EditText uname, password;
Button submit;
// Creating JSON Parser object
JSONParser jParser = new JSONParser();
private static final String TAG = "Login";
JSONObject json;
private static String url_login = "http://localhost:8080/ForgetMeNotApplication/Login";
//JSONArray incoming_msg = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewsById();
submit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// execute method invokes doInBackground() where we open a Http URL connection using the given Servlet URL
//and get output response from InputStream and return it.
new Login().execute();
}
});
}
private void findViewsById() {
uname = (EditText) findViewById(R.id.txtUser);
password = (EditText) findViewById(R.id.txtPass);
submit = (Button) findViewById(R.id.login);
}
private class Login extends AsyncTask<String, String, String>{
@Override
protected String doInBackground(String... args) {
// Getting username and password from user input
String username = uname.getText().toString();
String pass = password.getText().toString();
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("u",username));
params.add(new BasicNameValuePair("p",pass));
json = jParser.makeHttpRequest(url_login, "GET", params);
String s=null;
try {
s= json.getString("info");
Log.d("Msg", json.getString("info"));
if(s.equals("success")){
Intent login = new Intent(getApplicationContext(), home.class);
login.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(login);
finish();
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Android studio 说方法 getText()
必须从 UI 线程中的指令调用:uname.getText().toString();
和 password.getText().toString();
可能的解决方案??
制作 username
和 pass
login
class 变量并覆盖 onPreExcecute()
并执行此操作:
@Override
protected void onPreExecute() {
username = uname.getText().toString();
pass = password.getText().toString();
}
抛出异常是因为 doInBackground()
是从后台线程调用的。我会在 Login
class.
的构造函数中添加两个字符串参数
我想建议您在 Android 上获得更多关于 AsyncTasks
和线程的知识。比如官方文档中有这样一个页面:http://developer.android.com/guide/components/processes-and-threads.html。
您也可以看看这门课程:https://www.udacity.com/course/developing-android-apps--ud853。您可以学到很多 Android 框架的基础知识。
您正在从此处的后台线程访问 UI 线程:
String username = uname.getText().toString();
String pass = password.getText().toString();
您要做的只是将 username/password 字符串传递给您的后台任务构造函数,或者您可以将它们直接传递给执行方法。如果需要它们(就像你的那样),我更愿意将它们定义到构造函数中。
像
一样定义您的登录任务
String uname;
String password;
public Login(String username, String password({
this.uname = username;
this.password = password;
}
然后在 doInBackground() 中改用成员。
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("u",this.username));
params.add(new BasicNameValuePair("p",this.pass));
json = jParser.makeHttpRequest(url_login, "GET", params);
编辑 - 那么您的新 Login().execute() 调用看起来更像这样
new Login(uname.getText().toString(), password.getText().toString()).execute();
除非发生了我不知道的变化,否则这应该不是问题。 UI 元素无法从后台更新,但访问它们的 getter 从来都不是问题。
无论如何,您可以通过向 AsyncTask
添加一个构造函数来解决这个问题,该构造函数需要两个 String
然后在创建任务时发送它们。
private class Login extends AsyncTask<String, String, String>{
// member variables of the task class
String uName, pwd
public Login(String userName, String password) {
uName = userName;
pwd = password;
}
@Override
protected String doInBackground(String... args) {...}
并将它们传递到您的 onClick()
@Override
public void onClick(View arg0) {
// execute method invokes doInBackground() where we open a Http URL connection using the given Servlet URL
//and get output response from InputStream and return it.
// pass them here
new Login(uname.getText().toString(), password.getText().toString()).execute();
}
尝试通过 execute(param1, param1, ..., paramN)
方法将您的值传递给 Login AsyncTask
:
submit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
String username = uname.getText().toString();
String pass = password.getText().toString();
new Login().execute(username, pass);
}
});
}
private void findViewsById() {
uname = (EditText) findViewById(R.id.txtUser);
password = (EditText) findViewById(R.id.txtPass);
submit = (Button) findViewById(R.id.login);
}
private class Login extends AsyncTask<String, String, String>{
@Override
protected String doInBackground(String... args) {
// Getting username and password from user input
String username = args[0];
String pass = args[1];
我正在尝试为应用程序创建登录名。但是我有一个问题。
这是我的代码:
package com.forgetmenot.loginregister;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends Activity {
EditText uname, password;
Button submit;
// Creating JSON Parser object
JSONParser jParser = new JSONParser();
private static final String TAG = "Login";
JSONObject json;
private static String url_login = "http://localhost:8080/ForgetMeNotApplication/Login";
//JSONArray incoming_msg = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewsById();
submit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// execute method invokes doInBackground() where we open a Http URL connection using the given Servlet URL
//and get output response from InputStream and return it.
new Login().execute();
}
});
}
private void findViewsById() {
uname = (EditText) findViewById(R.id.txtUser);
password = (EditText) findViewById(R.id.txtPass);
submit = (Button) findViewById(R.id.login);
}
private class Login extends AsyncTask<String, String, String>{
@Override
protected String doInBackground(String... args) {
// Getting username and password from user input
String username = uname.getText().toString();
String pass = password.getText().toString();
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("u",username));
params.add(new BasicNameValuePair("p",pass));
json = jParser.makeHttpRequest(url_login, "GET", params);
String s=null;
try {
s= json.getString("info");
Log.d("Msg", json.getString("info"));
if(s.equals("success")){
Intent login = new Intent(getApplicationContext(), home.class);
login.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(login);
finish();
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Android studio 说方法 getText()
必须从 UI 线程中的指令调用:uname.getText().toString();
和 password.getText().toString();
可能的解决方案??
制作 username
和 pass
login
class 变量并覆盖 onPreExcecute()
并执行此操作:
@Override
protected void onPreExecute() {
username = uname.getText().toString();
pass = password.getText().toString();
}
抛出异常是因为 doInBackground()
是从后台线程调用的。我会在 Login
class.
我想建议您在 Android 上获得更多关于 AsyncTasks
和线程的知识。比如官方文档中有这样一个页面:http://developer.android.com/guide/components/processes-and-threads.html。
您也可以看看这门课程:https://www.udacity.com/course/developing-android-apps--ud853。您可以学到很多 Android 框架的基础知识。
您正在从此处的后台线程访问 UI 线程:
String username = uname.getText().toString();
String pass = password.getText().toString();
您要做的只是将 username/password 字符串传递给您的后台任务构造函数,或者您可以将它们直接传递给执行方法。如果需要它们(就像你的那样),我更愿意将它们定义到构造函数中。
像
一样定义您的登录任务String uname;
String password;
public Login(String username, String password({
this.uname = username;
this.password = password;
}
然后在 doInBackground() 中改用成员。
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("u",this.username));
params.add(new BasicNameValuePair("p",this.pass));
json = jParser.makeHttpRequest(url_login, "GET", params);
编辑 - 那么您的新 Login().execute() 调用看起来更像这样
new Login(uname.getText().toString(), password.getText().toString()).execute();
除非发生了我不知道的变化,否则这应该不是问题。 UI 元素无法从后台更新,但访问它们的 getter 从来都不是问题。
无论如何,您可以通过向 AsyncTask
添加一个构造函数来解决这个问题,该构造函数需要两个 String
然后在创建任务时发送它们。
private class Login extends AsyncTask<String, String, String>{
// member variables of the task class
String uName, pwd
public Login(String userName, String password) {
uName = userName;
pwd = password;
}
@Override
protected String doInBackground(String... args) {...}
并将它们传递到您的 onClick()
@Override
public void onClick(View arg0) {
// execute method invokes doInBackground() where we open a Http URL connection using the given Servlet URL
//and get output response from InputStream and return it.
// pass them here
new Login(uname.getText().toString(), password.getText().toString()).execute();
}
尝试通过 execute(param1, param1, ..., paramN)
方法将您的值传递给 Login AsyncTask
:
submit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
String username = uname.getText().toString();
String pass = password.getText().toString();
new Login().execute(username, pass);
}
});
}
private void findViewsById() {
uname = (EditText) findViewById(R.id.txtUser);
password = (EditText) findViewById(R.id.txtPass);
submit = (Button) findViewById(R.id.login);
}
private class Login extends AsyncTask<String, String, String>{
@Override
protected String doInBackground(String... args) {
// Getting username and password from user input
String username = args[0];
String pass = args[1];