1

I'm creating several AsyncTasks to send data to my server. In SendOnlyOneFact I send several images, gps positions, strings, sounds,... all converted to Base64 strings and then, my server replies me with an ID everytime it gets data, so I save it in the field "id_Data". My problem is that I need to get the replies of the server in order, that is to say, I need something similar to 'Asynctasks ordered', because I need them to do other actions.

I'm working in API 8. I appreciate any help. Here's my code.

In main procedure:

for (int k=0; k<activities.size(); k++){
new SendOnlyOneFact().execute(definition, act, null, k);
}

Class SendOnlyOneFact:

private class SendOnlyOneFact extends AsyncTask<Object, Void, Void>{
private HttpResponse response;
private int kkk;
private HttpClient httpClient;

@Override
protected void onPreExecute(){
    httpClient = new DefaultHttpClient();
}
@Override
protected void onProgressUpdate(Void... values){}
@Override
protected Void doInBackground(Object... params) {
    kkk = ((Integer) params[3]);
    actividades.get(kkk).saveData((android.app.Activity) params[1]);
    // Serializar los datos creados
    String cosa_serializada = actividades.get(kkk).getMeasure().serializeData(actividades.get(kkk), (android.app.Activity) params[1]);



    HttpHost targetHost = new HttpHost(((GateDefinition) params[0]).getServer(), ((GateDefinition) params[0]).getPort(), "http");

    HttpPost httpPost = new HttpPost("http://" + ((GateDefinition) params[0]).getServer() + ":" + ((GateDefinition) params[0]).getPort() + "/" + ((GateDefinition) params[0]).getWeb_service());
    // Also be sure to tell the server what kind of content we are sending
    httpPost.setHeader("content-type", "text/plain");
    try {
        StringEntity entity = new StringEntity(cosa_serializada, "UTF-8");
        entity.setContentType("text/plain");
        httpPost.setEntity(entity);

        // execute is a blocking call, it's best to call this code in a
        // thread separate from the ui's
        response = httpClient.execute(targetHost, httpPost);

        entity.consumeContent();
    } catch (SocketException ex){
        Log.e("SendOnlyOneFact", "No existe conexión con el servidor");
        ex.printStackTrace();
    } catch (Exception ex){
        ex.printStackTrace();
    } 
    return null;
}

@Override
protected void onPostExecute(Void result){
    if (response != null){
        try {
            this.get();
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (ExecutionException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        BufferedReader reader = null;
        String respuesta = null;
        try {
            reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()), 8192);
            respuesta = reader.readLine();
                actividades.get(kkk).getMeasure().setId_Data(respuesta);

            Log.i("onPostExecute SendOnlyOneFact", "Llegó un ID: " + respuesta);
                reader.close();
            } catch (IllegalStateException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SocketException ex){
                ex.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } else {
            // Entra aquí cuando ocurre una excepción
            // La IP del servidor es incorrecta
            // El servidor no está ejecutándose
            Toast.makeText(mActivity, "Imposible conectar con el servidor.", Toast.LENGTH_LONG).show();
        }
        // When HttpClient instance is no longer needed,
        // shut down the connection manager to ensure
        // immediate deallocation of all system resources
        httpClient.getConnectionManager().shutdown();
    }
}
4

3 回答 3

2

我认为你所追求的是一种序列化 AsyncTasks 执行的方法,为此你可以删除你的 for 循环并在 onPostExecute 中启动下一个 asyncTask。另一种方法是放弃 AsyncTasks 并使用 ThreadPoolExecutor.newSingleThreadExecutor。

于 2013-02-07T21:56:10.270 回答
0

试试下面的链接:

http://android-developers.blogspot.co.uk/2010/07/multithreading-for-performance.html

有一个部分处理并发,将帮助您确保返回的数据与正确的 AsyncTask 相关联。

于 2013-02-07T22:45:11.320 回答
0

看看这个演示项目以获得一些帮助。https://github.com/vitkhudenko/test_asynctask

具体来说,

            task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

            task.execute();

该演示项目应该让您更好地了解线程池的工作原理。

于 2013-02-07T21:08:22.373 回答