所以我正在构建这个Android应用程序并且我正在处理当用户输入错误的用户名或密码时要显示的错误消息。现在偶尔会显示错误消息。我得到一个名为
的异常android.view.viewroot $ calledfromwrongthreadexception
当我只研究时,作者基本上说当你使用AsyncTask时,在doinBackground方法中设置文本不是一个好主意。由于在onPostExecute中设置测试会随时显示该方法,无论登录是否成功,我提出的部分解决方案就是这个。
import java.util.ArrayList;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
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.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.SimpleAdapter;
import android.widget.TextView;
public class Login extends Activity {
static EditText alog;
static EditText apass;
JSONParser jsnParser = new JSONParser();
public static String url_login="...";
private static final String TAG_SUCCESS = "operation";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent it =getIntent();
setContentView(R.layout.activity_login);
alog=(EditText)findViewById(R.id.loginuser);
apass=(EditText)findViewById(R.id.loginpass);
Button btnLogin = (Button)findViewById(R.id.loggin);
Button btnRegister =(Button)findViewById(R.id.register2);
btnRegister.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent i=new Intent(Login.this, Registration.class);
startActivity(i);
}
});
btnLogin.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
new LoggerIn().execute();
}
});
}
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.login, menu);
return true;
}
class LoggerIn extends AsyncTask<String, String, String> {
@Override
protected String doInBackground(String... params) {
String logger=alog.getText().toString();
String passer=apass.getText().toString();
List <NameValuePair> prm=new ArrayList<NameValuePair>();
prm.add(new BasicNameValuePair("username", logger));
prm.add(new BasicNameValuePair("password", passer));
JSONObject jsn= jsnParser.makeHttpRequest(url_login, "POST", prm);
Log.d("Create Response", jsn.toString());
try {
boolean success=jsn.getBoolean(TAG_SUCCESS);
if (success == true) {
// successfully created product
Intent i = new Intent(getApplicationContext(), Home.class);
startActivity(i);
// closing this screen
finish();
} else {
// failed to create product
//onPostExecute
//TextView txt=(TextView)findViewById(R.id.login_error);
//txt.setText("The username or password you entered was wrong");
displayError();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void displayError() {
// dismiss the dialog after getting all products
// updating UI from Background Thread
TextView txt=(TextView)findViewById(R.id.login_error);
txt.setText("The username or password you entered was wrong");
}
}
}
但是,当我无法登录时,我必须在消息出现之前重复2到3次失败。有没有正确的方法来做到这一点?
答案 0 :(得分:2)
问题似乎是你试图在AsyncTask
内的UI线程上做一些事情。如果您想对UI线程进行更改(即显示Toast,设置TextView
等),请使用onPostExecute()
方法或使用您也可以使用runOnUiThread进行更改{ {1}}。
请参阅上述问题,进一步说明您所遇到的错误以及纠正方式:How to fix android.os.NetworkOnMainThreadException?
请在此处查看如何在doInBackground
内调用UI线程上的方法:
Android : Calling the methods on UI thread from AsyncTask doInBackground method
希望这有帮助。
答案 1 :(得分:0)
您只能从UI线程更新UI。从可以访问UI线程的方法中执行Asynctask中的所有UI调用,即onPreExecute()
,onProgressUpdate()
和onPostExecute()
。