1

我正在使用 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 线程,这些任务并行运行,但它们在彼此之间串行运行,这很耗时。所以相反,我试图在执行程序上执行它们但问题是这样我会丢失一些文件,这意味着当它们序列化运行时,我最终下载了 38 个文件,而在 Executor 上运行我最终得到了 20 .我很确定是这样,因为我在多线程代码中搞砸了一些东西所以我会把它发布到:

        @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 是一个长方法,它解析 json 文件,创建对象,然后将它们存储在 ArrayList 中,这就是可能存在问题的地方。

4

1 回答 1

0

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

查看您的代码,我发现互斥锁是一个静态变量,您可以使用它来跟踪您的线程。确保对互斥锁的操作是同步的,只是为了保持干净。但这不会给你带来问题......

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

于 2013-12-09T21:30:28.303 回答