我的代码完美无缺,但只有我点击按钮两次才能完成。如果我只点击一次,它将返回“limit_customers”= 0。
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.button_to_customers:
int limit_customers = 50;
// R1 = Radiobutton > inside RadioGroup
if(r1.isChecked()){
group_id = 0;
}else{ group_id = 1;}
if(the_list.get(0).getSelected() == true){
Log.e("list:", String.valueOf(the_list.get(0).getSelected()));
// This returns true at first click (it's correct)
if(group_id == 0){
Log.e("group:", String.valueOf(group_id));
// returns 0 at first click (it's correct)
limit_customers = get_customers_count();
Log.e("limit:", String.valueOf(limit_customers));
// returns 0 at first click (it's INCORRECT)
// at second click returns 3 (it's correct)
}
}
break;
}
}
这是返回count();
的函数public int get_customers_count(){
ExecutorService mExec = Executors.newSingleThreadExecutor();
mExec.execute(new Runnable() {
@Override
public void run() {
try{
SoapObject request = new SoapObject(NAMESPACE, "get_count_customers");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(URL + "/get_count_customers", envelope);
SoapObject rep = (SoapObject) envelope.bodyIn;
JSONArray jr = new JSONArray(rep.getPropertyAsString(0));
JSONObject jb = (JSONObject) jr.get(0);
amount_customers = jb.getInt("count");
}catch (Exception e){
Log.e("Error:", e.toString());
}
}
});
return amount_customers;
}
任何人都知道它会是什么?
编辑:我将所有答案都标记为正确,因为您的所有答案都是正确的,我会根据他们解决问题。谢谢。
答案 0 :(得分:1)
return amount_customers;
在您有机会针对服务器执行代码之前将调用(因为服务器调用在单独的线程中运行)。这就是为什么你得到0,下次你点击你的按钮,你将获得第一次通话的结果,第三次点击结果进行第二次通话等。
答案 1 :(得分:1)
get_customers_count
方法的实现执行异步runnable来填充amount_customers
。当您第一次单击JSON解析未完成时,类级别变量amount_customers
仍然是默认值(零)。在第一次和第二次点击之间的某个时刻,runnable完成并且行;
amount_customers = jb.getInt("count");
...正在运行。这意味着填充了类变量,从而产生显示正确值的日志输出。重要的是,第二次点击已经开始另一个异步任务,以便第二次重新填充amount_customers变量,而您没有看到它。
要直接得到答案,那么呼叫需要同步。但是,正如您已正确指出的那样,在I / O线程上进行网络通信的同步调用是坏消息(导致ANR)。您可能需要某种UI小部件,指示正在获取amount_customers的值。当从解析任务返回值时,您将需要调用侦听器方法(您传递给get_customers_count)以通知代码,该代码依赖于可以安全进行的值。在此期间,您还需要禁用按钮按钮,以便进一步(重复)请求。合理的UI看起来像这样;
非按下状态...(正常按钮)
_____________________
| |
| Button label |
|___________________|
点击后...(使用微调器通知用户正在发生的事情 - 禁用按钮)
_____________________
| |
| Button label {/} | ...{/} => spinner.
|___________________|
结果返回....(正常按钮)
_____________________
| |
| Button label |
|___________________|
然后执行依赖于结果的操作。
答案 2 :(得分:1)
使用AsyncTask
而不是线程,因为线程在后台运行,前台流没有查找/等待。
示例代码,
private class GetCustomersCont extends AsyncTask<Void, Void, Void> {
private int amount_customers = 0;
private ProgressDialog dialog=null;
@Override
protected void onPreExecute() {
dialog = new ProgressDialog(this);
dialog.setCancelable(false);
dialog.setMessage("Please Wait..");
dialog.show();
}
@Override
protected Void doInBackground(Void... params) {
try{
SoapObject request = new SoapObject(NAMESPACE, "get_count_customers");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(URL + "/get_count_customers", envelope);
SoapObject rep = (SoapObject) envelope.bodyIn;
JSONArray jr = new JSONArray(rep.getPropertyAsString(0));
JSONObject jb = (JSONObject) jr.get(0);
amount_customers = jb.getInt("count");
}catch (Exception e){
Log.e("Error:", e.toString());
}
return null;
}
@Override
protected void onPostExecute(Void result) {
if(dialog.isShowing())
dialog.dismiss();
Log.e("limit:", String.valueOf(limit_customers));
}
}
将onClick()
更改为
private GetCustomersCont mGetCustomersCont = null;
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.button_to_customers:
int limit_customers = 50;
// R1 = Radiobutton > inside RadioGroup
if(r1.isChecked()){
group_id = 0;
}else{ group_id = 1;}
if(the_list.get(0).getSelected() == true){
Log.e("list:", String.valueOf(the_list.get(0).getSelected()));
// This returns true at first click (it's correct)
if(group_id == 0){
Log.e("group:", String.valueOf(group_id));
mGetCustomersCont = new GetCustomersCont();
mGetCustomersCont.execute();
}
}
break;
}
}