我从android(3天前)开始,我无法得到我想要的解决方案。所以,我在这里读了很多关于asyncTask的帖子,现在我确定我感到困惑。
首先,这是我的第一个问题,所以我希望我至少能够做到这一点。
我想要的是有一个类连接到某个服务器及其结果。之后分析json或xml。
所以这就是我所做的。 这是我的活动类(从主要活动中调用)
public class LogIn extends Activity implements OnClickListener {
Button btn =null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
btn = (Button) findViewById(R.id.btn_login);
btn.setOnClickListener( this);
}
public void onClick(View view) {
HttpResponse response;
Intent data = new Intent();
//---get the EditText view---
EditText txt_user = (EditText) findViewById(R.id.et_un);
EditText txt_pwd = (EditText) findViewById(R.id.et_pw);
// aca tengo q llamar al conectar y chequear en BD
ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("usr", txt_user.getText().toString()));
postParameters.add(new BasicNameValuePair("pass", txt_pwd.getText().toString()));
String URL="whatever";
try {
response= new ConectServer(URL, postParameters).execute().get();
LeerAutentificacionXml l= new LeerAutentificacionXml(response);
String s=l.Transformar();
data.setData(Uri.parse(s.toString()));
setResult(RESULT_OK, data);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//---set the data to pass back---
// data.setData(Uri.parse(txt_user.getText().toString()+ " " + Uri.parse(txt_pwd.getText().toString())));
// setResult(RESULT_OK, data);
//---closes the activity---
finish();
} }
这是我连接到Web服务的类。
public class ConectServer extends AsyncTask <Void, Void, HttpResponse> {
private String URL=null;
private ArrayList<NameValuePair> postParameters=null;
/** Single instance of our HttpClient */
private HttpClient mHttpClient;
/** The time it takes for our client to timeout */
public static final int HTTP_TIMEOUT = 30 * 1000;
public ConectServer(String url, ArrayList<NameValuePair> p) {
this.URL=url;
this.postParameters=p;
}
private HttpClient getHttpClient() {
if (mHttpClient == null) {
mHttpClient = new DefaultHttpClient();
final HttpParams params = mHttpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params, HTTP_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, HTTP_TIMEOUT);
ConnManagerParams.setTimeout(params, HTTP_TIMEOUT);
}
return mHttpClient;
}
/**
* Performs an HTTP Post request to the specified url with the
* specified parameters.
*
* @param url The web address to post the request to
* @param postParameters The parameters to send via the request
* @return The result of the request
* @throws Exception
*/
@Override
protected HttpResponse doInBackground(Void... params) {
// TODO Auto-generated method stub
HttpResponse response = null;
try {
HttpClient client = getHttpClient();
HttpPost request = new HttpPost(this.URL);
UrlEncodedFormEntity formEntity;
formEntity = new UrlEncodedFormEntity(this.postParameters);
request.setEntity(formEntity);
response = client.execute(request);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
public void onPreExecute() {
super.onPreExecute();
}
protected void onPostExecute(HttpResponse response) {
super.onPostExecute(response);
}}
我通过听众阅读了一些设计模式,但首先我想更好地理解为什么这不起作用。 我从服务器收到一个错误,我想知道这是否正确或者哪个大的newby失败了。
提前谢谢。答案 0 :(得分:2)
调用asyncTask.get()
等待AsyncTask
完成,然后返回结果。它基本上违背了AsyncTask
的目的 - AsyncTask
的重点是长时间运行的任务在后台线程中执行,并且UI线程在此期间未被阻止。当你调用.get()
时,它会阻止等待后台线程完成的UI线程。
所以,不要使用get()
并移动ll在onPostExecute(..)
可用结果时应该执行的操作。像这样:
protected void onPostExecute(HttpResponse response) {
super.onPostExecute(response);
LeerAutentificacionXml l= new LeerAutentificacionXml(response);
String s=l.Transformar();
data.setData(Uri.parse(s.toString()));
}
当然,您必须将一些引用(data
?)传递给AsyncTask
(通过构造函数或其他方式)。
答案 1 :(得分:1)
尝试在异步任务中封装所有网络代码,以便您可以这样调用它:
EditText txt_user = (EditText) findViewById(R.id.et_un);
EditText txt_pwd = (EditText) findViewById(R.id.et_pw);
new LoginTask(txt_user.getText(), txt_pwd.getText(), this).execute();
根据您问题中的代码, LoginTask
如下所示:
public class LoginTask extends AsyncTask<Void, Void, String> {
// The URL probably won't change, so keep it in a static field
private final static String URL = "http://....";
private final String username;
private final String password;
private final Activity activity;
/*
* Pass all data required to log in and handle the result here.
*/
public LoginTask(final String username, final String password, final Activity activity) {
this.username = username;
this.password = password;
this.activity = activity;
}
/*
* Do all the network IO and time-consuming parsing in here,
* this method will be invoked in its own thread, not blocking the UI.
*/
@Override
protected String doInBackground(Void... params) {
HttpClient client = getHttpClient();
try {
HttpEntity formEntity = new UrlEncodedFormEntity(Arrays.asList(
new BasicNameValuePair("usr", username),
new BasicNameValuePair("pass", password)));
HttpPost request = new HttpPost(URL);
request.setEntity(formEntity);
HttpResponse response = client.execute(request);
LeerAutentificacionXml l= new LeerAutentificacionXml(response);
return l.Transformar();
} catch (IOException ex) {
// properly log your exception, don't just printStackTrace()
// as you can't pinpoint the location and it might be cut off
Log.e("LOGIN", "failed to log in", ex);
} finally {
client.getConnectionManager().shutdown();
}
}
private HttpClient getHttpClient() {
return null; // insert your previous code here
}
/*
* This again runs on the UI thread, so only do here
* what really needs to run on the UI thread.
*/
@Override
protected void onPostExecute(String response) {
Intent data = new Intent();
data.setData(Uri.parse(response));
activity.setResult(Activity.RESULT_OK, data);
}
}
即使您没有将登录视为“长时间运行的任务”,根据定义,任何涉及网络IO的任务都是由于您无法控制的原因而可能挂起,超时等的任务。
拥有多个执行网络IO的类没有任何问题,只要您仔细封装上述LoginTask
示例中的详细信息即可。尝试编写此类型的两个,三个AsyncTask
类,然后查看是否可以将常用部分提取到常见的“Web内容”AsyncTask
中。但不要一次完成。