0

I am trying to read data from a CSV file and then send those data to the server for handling, however, when I click the button to read the data from the file and then try to send to server, error exists and my app colses unexpectedly.

Below are the messages in error log:

08-06 17:04:32.168: E/AndroidRuntime(10468): FATAL EXCEPTION: main
08-06 17:04:32.168: E/AndroidRuntime(10468): java.lang.IllegalStateException: Cannot execute task: the task is already running.
08-06 17:04:32.168: E/AndroidRuntime(10468):    at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:575)
08-06 17:04:32.168: E/AndroidRuntime(10468):    at android.os.AsyncTask.execute(AsyncTask.java:534)
08-06 17:04:32.168: E/AndroidRuntime(10468):    at Android.Chico.Chico$3.onClick(Chico.java:307)
08-06 17:04:32.168: E/AndroidRuntime(10468):    at android.view.View.performClick(View.java:4084)
08-06 17:04:32.168: E/AndroidRuntime(10468):    at android.view.View$PerformClick.run(View.java:16966)
08-06 17:04:32.168: E/AndroidRuntime(10468):    at android.os.Handler.handleCallback(Handler.java:615)
08-06 17:04:32.168: E/AndroidRuntime(10468):    at android.os.Handler.dispatchMessage(Handler.java:92)
08-06 17:04:32.168: E/AndroidRuntime(10468):    at android.os.Looper.loop(Looper.java:137)
08-06 17:04:32.168: E/AndroidRuntime(10468):    at android.app.ActivityThread.main(ActivityThread.java:4745)
08-06 17:04:32.168: E/AndroidRuntime(10468):    at java.lang.reflect.Method.invokeNative(Native Method)
08-06 17:04:32.168: E/AndroidRuntime(10468):    at java.lang.reflect.Method.invoke(Method.java:511)
08-06 17:04:32.168: E/AndroidRuntime(10468):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
08-06 17:04:32.168: E/AndroidRuntime(10468):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
08-06 17:04:32.168: E/AndroidRuntime(10468):    at dalvik.system.NativeStart.main(Native Method)

I saw same kind of error before, I know this exception may appear as AsyncTask can be executed once, therefore I create a new AsyncTask everytime However, error appears, so I would like to ask what may be the causes?

Here is my code:

public class Chico extends Activity {
    GrabURL grab;
    Button btnfinish;
    Button btninsert;
    List<String[]> CSVData = new ArrayList<String[]>();
    Boolean Insert = false;
    Boolean Continue = false;
    int numrecord=0;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        //create the activity
        super.onCreate(savedInstanceState);

        //set up the layout
        setContentView(R.layout.activity_chico);

        btninsert = (Button) findViewById(R.id.Insert);
        if(new File(Environment.getExternalStorageDirectory()+"/Chico/record.csv").exists()){
            btninsert.setVisibility(View.VISIBLE);
        }else{
            btninsert.setVisibility(View.GONE);
        }

        btnfinish = (Button) findViewById(R.id.Finish);
        btnfinish.setVisibility(View.GONE);
        grab = new GrabURL();

        btninsert.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                if(!Continue){
                    Insert = true;
                    Continue = true;
                    btninsert.setVisibility(View.GONE);
                    try {
                        BufferedReader reader = new BufferedReader(new FileReader(Environment.getExternalStorageDirectory()+"/Chico/record.csv"));
                        try {
                            String line;
                            while ((line = reader.readLine()) != null){
                                String[] RowData = line.split(",");
                                CSVData.add(RowData);
                            }
                        } catch (IOException ex) {

                        }
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }else{
                    grab = new GrabURL();
                }
                if(numrecord==CSVData.size())
                    btnfinish.setVisibility(View.VISIBLE);
                while(numrecord<CSVData.size()){
                    grab.onPreExecute("TechID", Build.SERIAL);
                    grab.onPreExecute("ClientID", CSVData.get(numrecord)[0]);
                    grab.onPreExecute("SiteID", CSVData.get(numrecord)[1]);
                    grab.onPreExecute("Type", CSVData.get(numrecord)[2]);
                    grab.onPreExecute("LogTime", CSVData.get(numrecord)[3]);
                    if(CSVData.get(numrecord)[2]=="Checkin"){
                        grab.onPreExecute("Remark", "");
                    }else{
                        grab.onPreExecute("Remark", CSVData.get(numrecord)[4]);
                    }
                    grab.execute(new String[]{"http://192.168.1.150/check.php"});
                }
            }
        });

        btnfinish.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                finish();
            }
        });
    }

    private class GrabURL extends AsyncTask<String, Void, Void>{
        //ArrayList object for storing the string pairs
        ArrayList<NameValuePair> nameValuePairs;

        public GrabURL() { 
            //constructor of the class
            nameValuePairs = new ArrayList<NameValuePair>(); 
          } 


        protected void onPreExecute(String key, String value) {
            //store the pair of values into the ArrayList 
            nameValuePairs.add(new BasicNameValuePair(key,value));
            }

        @Override
        protected Void doInBackground(String... urls) {
            // TODO Auto-generated method stub
            //Operation being executed in another thread
            try{
                //set up the type of HTTPClient
                HttpClient client = new DefaultHttpClient();
                //set up the location of the server
                HttpPost post = new HttpPost(urls[0]);
                //translate form of pairs to UrlEncodedFormEntity 
                UrlEncodedFormEntity ent = new UrlEncodedFormEntity(nameValuePairs,HTTP.UTF_8);
                //set up the entity being sent by post method
                post.setEntity(ent);
                //execute the url and post the values
                //client.execute(post);
                HttpResponse responsePOST = client.execute(post); 
                HttpEntity resEntity = responsePOST.getEntity();
                line = EntityUtils.toString(resEntity);
             } catch (Exception e) {
                 //catch the exception
                line = "Can't connect to server";
             }
            return null;
        }

        protected void onPostExecute(Void unused) {
            if(Insert){
                if(line.equals("Check in record has been inserted!") ||
                        line.equals("Check out record has been inserted!")){
                        btninsert.setVisibility(View.VISIBLE);
                        numrecord++;
                } else if(line.equals("Can't connect to server")) {
                        btnfinish.setVisibility(View.VISIBLE);
                } 
            }
        }
    }
}
Conrad
  • 933
  • 4
  • 19
  • 34

1 Answers1

1

If you look carefuly at your error log, you will see the error occurs at line 307 of your Chico.java class. So Double click this line or scroll to this line in code to see where it goes wrong.

But I think it's because you are calling the onPreExecute() method manually and multiple times. If you read the howto for using AsyncTask for Android on this site : How to Use AsyncTask for Android and the Android developers site, you can read that you may not call onPreExecute(), doInBackground() and onPostExecute() manually because they are called automatically by Android when you call the execute() method.

So, I think best way for this is to add your nameValuePairs in an ArrayList and add it as a parameter to the constructor of your AsyncTask. Afterwards, execute() your GrabURL Asynctask this way:

grab.execute("http://192.168.1.150/check.php");

Because it's not needed to add your params in an array format to the execute() method. You do not have to change any code in your doInBackground() method.

Good luck!

Have a nice development.

Kr

pinyin_samu
  • 174
  • 1
  • 12
  • Line 307 is this line "grab.execute(new String[]{"http://192.168.1.150/check.php"});" Actually, the way of using the AsyncTask is the same as what I do before, so I think it may not be the cause of problem. – Conrad Aug 07 '12 at 01:29
  • @user1502740 I didn't take mutch attention on it before but you launch the AsyncTask in a while loop. I also tested this: when I initialize the task before my while-loop (the same way you do), I get the same error. If I call new GrabURL().execute(); in the while loop, it works perfect. In your case you will always run the same object from the task again, but you have to run a new object from the AsyncTask. Solution: run something like new GrabURL(ArrayList).execute(); in your while loop with ArrayList a list of the parameters you pass to onPreExecute(). Kr – pinyin_samu Aug 07 '12 at 08:28
  • thank you for helping, I take on your suggestion and the task has finished – Conrad Aug 07 '12 at 09:48
  • You're welcome. Fine to hear it works. Have a nice development. Kr – pinyin_samu Aug 07 '12 at 13:24