Multiple AsyncTasks issue on Android Spinner

2019-06-25 08:08发布

I'm getting some error. I know what is the problem but I don't know how to fix it.

I've 4 spinner. Every spinner related one asynctask. For short, When I select one item on spinner1 , execute second asynctask that populate spinner2 (selected item add to second asynctask as parameter) Continues in this way.

But before end of first asynctask, spinner2 can't populate. In this case I'm getting error. How to fix it ? How to make when first task finish, second task work ?

Here is the code;

First task

public class ilceDoldur extends AsyncTask<String[],String[],String[]>{

        @Override
        protected String[] doInBackground(String[]... params) {
            SoapObject request = new SoapObject(NAMESPACE, "ILCEGetir");
            SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
            envelope.dotNet = true;     
            envelope.setOutputSoapObject(request);
            HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
            androidHttpTransport.debug = true;

           try {

           androidHttpTransport.call("http://tempuri.org/ILCEGetir", envelope);
           SoapObject response = (SoapObject) envelope.getResponse();
           ilceList = new String[response.getPropertyCount()];

          for(int i=0;i<response.getPropertyCount();i++){          
                   ilceList[i] = response.getPropertyAsString(i).toString().trim();    
          }      
    } 
            catch (Exception e) {           
                e.printStackTrace();
           }    
            return ilceList;
        }

        protected void onPostExecute(String[] ilceList){
            ilceSpinner = (Spinner) findViewById(R.id.spinner1);
            ArrayAdapter<String> ilce_adapter = new ArrayAdapter<String>(NormalAnasayfa.this,android.R.layout.simple_spinner_item, ilceList);
            ilce_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            ilceSpinner.setAdapter(ilce_adapter);
            kontrol=true;
        }
    }

Second Task

public class semtDoldur extends AsyncTask<String,String[],String[]>{

        @Override
        protected String[] doInBackground(String... ParamIlce) {
            PropertyInfo ilce = new PropertyInfo();
            ilce.name= "ilce";
            ilce.setValue(ParamIlce);
            ilce.type = PropertyInfo.STRING_CLASS;

            SoapObject request = new SoapObject(NAMESPACE, "SEMTGetir");
            request.addProperty(ilce);

            SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
            envelope.bodyOut=request;
            envelope.dotNet = true; 
            envelope.setOutputSoapObject(request);

            HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
            androidHttpTransport.debug = true;

           try {

           androidHttpTransport.call("http://tempuri.org/SEMTGetir", envelope);
           SoapObject response = (SoapObject) envelope.getResponse();
           semtList = new String[response.getPropertyCount()];

          for(int i=0;i<response.getPropertyCount();i++){          
                   semtList[i] = response.getPropertyAsString(i).toString().trim();    
          }      
    } 
            catch (Exception e) {           
                e.printStackTrace();
           }
            return semtList;
        }

        protected void onPostExecute(String[] semtList){
            semtSpinner = (Spinner) findViewById(R.id.spinner2);
            ArrayAdapter<String> semt_adapter = new ArrayAdapter<String>(NormalAnasayfa.this, android.R.layout.simple_spinner_item, semtList);
            semt_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            semtSpinner.setAdapter(semt_adapter);
            kontrol=true;
        }
    }

onCreate()

new ilceDoldur().execute();

        if(kontrol==true){
            kontrol=false;
            ilceSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {

                public void onItemSelected(AdapterView<?> arg0, View arg1,
                        int arg2, long arg3) {
                    secilenIlce = ilceSpinner.getSelectedItem().toString().trim();
                    new semtDoldur().execute(secilenIlce);
                }
                public void onNothingSelected(AdapterView<?> arg0) {}
            });
        }

Edit: I get data from my web service and populate spinner1. Where the data(spinner1 selected item) will I get? and Where I populate spinner2 execute second task?

3条回答
男人必须洒脱
2楼-- · 2019-06-25 08:52

Just change onPostExcecute

    protected void onPostExecute(String[] ilceList){
        ilceSpinner = (Spinner) findViewById(R.id.spinner1);
        ArrayAdapter<String> ilce_adapter = new ArrayAdapter<String>(NormalAnasayfa.this,android.R.layout.simple_spinner_item, ilceList);
        ilce_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        ilceSpinner.setAdapter(ilce_adapter);
        ilceSecildi();
        }    
    }

to

    protected void onPostExecute(String[] ilceList){
        ilceSpinner = (Spinner) findViewById(R.id.spinner1);
        ArrayAdapter<String> ilce_adapter = new ArrayAdapter<String>(getApplicationContext(),android.R.layout.simple_spinner_item, ilceList);
        ilce_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        ilceSpinner.setAdapter(ilce_adapter);
        ilceSecildi();
        }    
    }
查看更多
虎瘦雄心在
3楼-- · 2019-06-25 08:58

From what I understand of the problem you are saying that you have multiple AsyncTasks which control the contents of multiple Spinners. You do some interaction that causes Spinner1 to be populated and immediately do another interaction that should cause Spinner2 to be populated, but the observed behavior is that Spinner2 does not populate until Spinner1 finishes population.

This is because the default behavior for AsyncTasks is for all of them in a process to execute serially. If you want AsyncTasks to run in parallel use AsyncTask.executeOnExecutor() and specify the thread pool executor. Read the docs for AsyncTask carefully though, the default parallelism behavior has changed over time.

查看更多
小情绪 Triste *
4楼-- · 2019-06-25 09:04

I find solution!

get data from web service:

private void ilceDoldur(){
        SoapObject request = new SoapObject(NAMESPACE, "ILCEGetir");
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.dotNet = true;     
        envelope.setOutputSoapObject(request);
        HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
        androidHttpTransport.debug = true;

       try {

       androidHttpTransport.call("http://tempuri.org/ILCEGetir", envelope);
       SoapObject response = (SoapObject) envelope.getResponse();
       ilceList = new String[response.getPropertyCount()];

      for(int i=0;i<response.getPropertyCount();i++){          
               ilceList[i] = response.getPropertyAsString(i).toString().trim();    
      }      
} 
        catch (Exception e) {           
            e.printStackTrace();
       }    
    }

my AsyncTask:

public class ilceDoldur extends AsyncTask<String,String[],String[]>{

        @Override
        protected String[] doInBackground(String... params) {
            ilceDoldur();
            return ilceList;
        }

        protected void onPostExecute(String[] ilceList){
            ilceSpinner = (Spinner) findViewById(R.id.spinner1);
            ArrayAdapter<String> ilce_adapter = new ArrayAdapter<String>(NormalAnasayfa.this,android.R.layout.simple_spinner_item, ilceList);
            ilce_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            ilceSpinner.setAdapter(ilce_adapter);
            ilceSecildi();
            }    
        }

Get spinner1 selected item and start second asynctask:

public String ilceSecildi(){
        ilceSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {

            public void onItemSelected(AdapterView<?> arg0, View arg1,
                    int arg2, long arg3) {
                secilenIlce = ilceSpinner.getSelectedItem().toString().trim();
                new semtDoldurAsync(secilenIlce).execute();
            }
            public void onNothingSelected(AdapterView<?> arg0) {}
        });
        return secilenIlce;
    }

execute first task in onCreate:

new ilceDoldur().execute();
查看更多
登录 后发表回答