为什么我的 AsyncTask 会冻结我的 UI 线程?
Why does my AsyncTask freeze my UI Thread?
我有这个问题:当我在表单中插入和提交数据时,我希望 AsyncTask 开始检查一切是否正常。
在我现在面临的具体情况下,我想验证输入的用户名是否还没有被使用过,所以我希望它去服务器并通过 php 查询用户的数据库。
我希望当整个事情开始时,用户屏幕不会被阻塞,也就是说,我想让用户无论如何都可以在屏幕内移动。
我附上代码:
public class ControlloUsername extends AsyncTask<String, Void, String> {
AlertDialog a;
Context context;
public ControlloUsername(Context ct) {
// TODO Auto-generated constructor stub
context = ct;
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
}
@Override
protected void onPostExecute(String result) { //sync
// TODO Auto-generated method stub
}
@Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
}
@Override
protected String doInBackground(String... params) { //sync
// TODO Auto-generated method stub
String username = params[0];
String login_url = Connector.db + "script/usercontrol.php";
String resultado = "";
URL u = null;
try {
u = new URL(login_url);
} catch (MalformedURLException e) {
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
resultado = writer.toString();
}
HttpURLConnection http = null;
try {
http = (HttpURLConnection) u.openConnection();
} catch (IOException e) {
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
resultado = writer.toString();
}
try {
http.setRequestMethod("POST");
} catch (ProtocolException e) {
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
resultado = writer.toString();
}
http.setDoInput(true);
http.setDoOutput(true);
http.setConnectTimeout(7000);
try {
OutputStream out = http.getOutputStream();
BufferedWriter bf = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
String post_data = URLEncoder.encode("username", "UTF-8") + "=" + URLEncoder.encode(username, "UTF-8");
bf.write(post_data);
bf.flush();
bf.close();
out.close();
InputStream in = http.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in, "iso-8859-1"));
String result = "";
String line = "";
while ((line = br.readLine()) != null) {
result += line;
}
bf.close();
in.close();
http.disconnect();
return result;
} catch (ConnectException e) {
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
resultado = "CONNECT" + writer.toString();
Log.d("PRINT", "CONNECT");
} catch (UnsupportedEncodingException e) {
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
resultado = "UNSUPPORTEDENCODING" + writer.toString();
Log.d("PRINT", "UNSUPPORTEDENCODING");
} catch (ProtocolException e) {
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
resultado = "PROTOCOL" + writer.toString();
Log.d("PRINT", "PROTOCOL");
} catch (MalformedURLException e) {
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
resultado = "MALFORMEDURL" + writer.toString();
Log.d("PRINT", "MALFORMEDURL");
} catch (IOException e) {
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
resultado = "IO" + writer.toString();
Log.d("PRINT", "IO");
}
return resultado;
}
}
RegisterActivity
String u = user.getText().toString();
ControlloUsername bg = new ControlloUsername(this);
try {
String res = bg.execute(u).get();
Log.d("PRINT", res);
if (res.contains("...
听说是execute().get()和AsyncTask自身方法的问题
您可以在 AsyncTask
完成后使用接口取回结果。在你的 AsyncTask 中:
onFinishListener mListener; // Create a variable for your interface
// Define the interface & callbacks
public interface onFinishListener{
// Replace 'variableType' with the appropriate type for your result
void onFinish(variableType myResult);
}
public void setOnFinishListener(onFinishListener l){
mListener = l;
}
@Override
protected void onPostExecute(variableType result){
if(mListener != null){
mListener.onFinish(result);
}
}
然后在 Activity 中,确保设置接口:
MyAsyncTask task = new MyAsyncTask();
task.execute();
task.setOnFinishListener(new MyAsyncTask.onFinishListener(){
@Override
public void onFinish(variableType myResult){
// The task has finished and you can now use the result
}
});
我有这个问题:当我在表单中插入和提交数据时,我希望 AsyncTask 开始检查一切是否正常。 在我现在面临的具体情况下,我想验证输入的用户名是否还没有被使用过,所以我希望它去服务器并通过 php 查询用户的数据库。 我希望当整个事情开始时,用户屏幕不会被阻塞,也就是说,我想让用户无论如何都可以在屏幕内移动。
我附上代码:
public class ControlloUsername extends AsyncTask<String, Void, String> {
AlertDialog a;
Context context;
public ControlloUsername(Context ct) {
// TODO Auto-generated constructor stub
context = ct;
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
}
@Override
protected void onPostExecute(String result) { //sync
// TODO Auto-generated method stub
}
@Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
}
@Override
protected String doInBackground(String... params) { //sync
// TODO Auto-generated method stub
String username = params[0];
String login_url = Connector.db + "script/usercontrol.php";
String resultado = "";
URL u = null;
try {
u = new URL(login_url);
} catch (MalformedURLException e) {
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
resultado = writer.toString();
}
HttpURLConnection http = null;
try {
http = (HttpURLConnection) u.openConnection();
} catch (IOException e) {
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
resultado = writer.toString();
}
try {
http.setRequestMethod("POST");
} catch (ProtocolException e) {
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
resultado = writer.toString();
}
http.setDoInput(true);
http.setDoOutput(true);
http.setConnectTimeout(7000);
try {
OutputStream out = http.getOutputStream();
BufferedWriter bf = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
String post_data = URLEncoder.encode("username", "UTF-8") + "=" + URLEncoder.encode(username, "UTF-8");
bf.write(post_data);
bf.flush();
bf.close();
out.close();
InputStream in = http.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in, "iso-8859-1"));
String result = "";
String line = "";
while ((line = br.readLine()) != null) {
result += line;
}
bf.close();
in.close();
http.disconnect();
return result;
} catch (ConnectException e) {
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
resultado = "CONNECT" + writer.toString();
Log.d("PRINT", "CONNECT");
} catch (UnsupportedEncodingException e) {
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
resultado = "UNSUPPORTEDENCODING" + writer.toString();
Log.d("PRINT", "UNSUPPORTEDENCODING");
} catch (ProtocolException e) {
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
resultado = "PROTOCOL" + writer.toString();
Log.d("PRINT", "PROTOCOL");
} catch (MalformedURLException e) {
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
resultado = "MALFORMEDURL" + writer.toString();
Log.d("PRINT", "MALFORMEDURL");
} catch (IOException e) {
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
resultado = "IO" + writer.toString();
Log.d("PRINT", "IO");
}
return resultado;
}
}
RegisterActivity
String u = user.getText().toString();
ControlloUsername bg = new ControlloUsername(this);
try {
String res = bg.execute(u).get();
Log.d("PRINT", res);
if (res.contains("...
听说是execute().get()和AsyncTask自身方法的问题
您可以在 AsyncTask
完成后使用接口取回结果。在你的 AsyncTask 中:
onFinishListener mListener; // Create a variable for your interface
// Define the interface & callbacks
public interface onFinishListener{
// Replace 'variableType' with the appropriate type for your result
void onFinish(variableType myResult);
}
public void setOnFinishListener(onFinishListener l){
mListener = l;
}
@Override
protected void onPostExecute(variableType result){
if(mListener != null){
mListener.onFinish(result);
}
}
然后在 Activity 中,确保设置接口:
MyAsyncTask task = new MyAsyncTask();
task.execute();
task.setOnFinishListener(new MyAsyncTask.onFinishListener(){
@Override
public void onFinish(variableType myResult){
// The task has finished and you can now use the result
}
});