在Executor上执行AsyncTasks不会获取所有数据

时间:2013-11-14 09:17:12

标签: multithreading android-asynctask

我正在使用asyncTask通过互联网下载一些文件。这是我编写的代码

            downloadUrl task = new downloadUrl(url1,"jsonData1","/sdcard/appData/LocalJson/jsonData1",context);
            task.execute();

            downloadUrl task1 = new downloadUrl(url2,"jsonData2","/sdcard/appData/LocalJson/jsonData2",context);
            task1.execute();

            downloadUrl task2 = new downloadUrl(url3,"jsonData3","/sdcard/appData/LocalJson/jsonData3",context);
            task2.execute();

            downloadUrl task3 = new downloadUrl(url4,"jsonData4","/sdcard/appData/LocalJson/jsonData4",context);
            task3.execute();

现在,考虑到UI-Thread,这些任务并行运行,但它们彼此之间进行了序列化,这非常耗时。所以相反,我试图在执行程序上执行它们但问题是这样我错过了一些文件,这意味着当它们运行序列化时我最终会在Executor上运行时最终下载38个文件我很确定那是因为我在多线程代码中搞砸了一些东西所以我会把它发布到:

        @Override
        protected String doInBackground(String... args) {               


            downloadAndStoreJson(url,targetFolder);
            JSONObject jsonObj = loadJSONObject(pathForLoad);
            try {
                processJsonData(jsonObj);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }




            return "done"; 
        }

        @Override
        protected void onPostExecute(String result) {

            s(targetFolder+" Finished!");
            ++mutex;

            progressBar.setProgress(25*mutex);

            if(mutex==4){
                mutex=0;
                progressBar.setProgress(100);
                progressBar.dismiss();

                s(monuments.size());

                Intent intent = new Intent (getApplicationContext(),NextClass.class);
                intent.putExtra("monuments", monuments);
                startActivity(intent);
            }

        }



   private void downloadAndStoreJson(String url,String tag){

  JSONParser jParser = new JSONParser();
  JSONObject json = jParser.getJSONFromUrl(url);            

  String jsonString = json.toString();              
  byte[] jsonArray = jsonString.getBytes();

  File fileToSaveJson = new File("/sdcard/appData/LocalJson/",tag);



    BufferedOutputStream bos;
    try {
        bos = new BufferedOutputStream(new FileOutputStream(fileToSaveJson));
        bos.write(jsonArray);
        bos.flush();
        bos.close();

    } catch (FileNotFoundException e4) {
        // TODO Auto-generated catch block
        e4.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    finally {
        jsonArray=null;
        jParser=null;
        System.gc();
    }

  }





  private JSONObject loadJSONObject(String path){

    JSONObject jsonObj = null;          
    File readFromJson = new File(path); 


    byte[] lala;
    try {
        lala= org.apache.commons.io.FileUtils.readFileToByteArray(readFromJson);
        s("---------------"+lala.length);
        String decoded = new String(lala, "UTF-8");
        jsonObj = new JSONObject(decoded);
    } catch (IOException e5) {
        // TODO Auto-generated catch block
        e5.printStackTrace();
    } catch (JSONException e) {
        // TODO Auto-generated catch block
        e.printStackTrace(); 
    }

    return jsonObj;         
  }

和processJsonData是一个long方法,它解析json文件,创建对象,然后将它们存储在ArrayList中,这就是可能存在问题的地方。

1 个答案:

答案 0 :(得分:0)

您需要确保您的代码是可重入的,这意味着必须能够同时由多个线程运行它。或者,如果某些代码用于同步线程之间的执行,则需要确保它是synchronized

查看代码,我发现互斥锁是一个静态变量,用于跟踪线程。确保互斥锁上的操作同步,以保持其清洁。但那不会给你带来麻烦......

我在这段代码片段中没有看到您的错误,要么我没有看到问题,要么可能位于其他一些方法中?你能分享一下“downloadAndStoreJson”吗?