Android按钮仅在单击两次时才有效

时间:2013-10-18 11:35:26

标签: android button

我的代码完美无缺,但只有我点击按钮两次才能完成。如果我只点击一次,它将返回“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;
}

任何人都知道它会是什么?

编辑:我将所有答案都标记为正确,因为您的所有答案都是正确的,我会根据他们解决问题。谢谢。

3 个答案:

答案 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;
        }
    }