使用AsyncTask将数据发送到服务器时出错

时间:2012-08-06 09:12:35

标签: android exception exception-handling android-asynctask illegalstateexception

我正在尝试从CSV文件读取数据,然后将这些数据发送到服务器进行处理,但是,当我单击按钮从文件中读取数据然后尝试发送到服务器时,错误存在且我的app意外地收到了。

以下是错误日志中的消息:

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)

我之前看过同样的错误,我知道这个异常可能会出现,因为AsyncTask可以执行一次,因此我每次都会创建一个新的AsyncTask然而,出现错误,所以我想问一下可能是什么原因?

这是我的代码:

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);
                } 
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

如果您仔细查看错误日志,您将看到错误发生在Chico.java类的第307行。所以双击这一行或在代码中滚动到这一行,看看它出错了。

但我认为这是因为你手动多次调用onPreExecute()方法。如果你在这个网站上阅读了使用AsyncTask for Android的指南:How to Use AsyncTask for AndroidAndroid developers site,你可以读到你不能手动调用onPreExecute(),doInBackground()和onPostExecute(),因为它们是调用execute()方法时由Android自动调用。

所以,我认为最好的方法是在ArrayList中添加nameValuePairs,并将其作为参数添加到AsyncTask的构造函数中。然后,以这种方式执行()你的GrabURL Asynctask:

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

因为不需要将数组格式的params添加到execute()方法中。您不必更改doInBackground()方法中的任何代码。

祝你好运!

有一个很好的发展。