1

I am using countdownlatch as in example below. Here BackgroundDataPopulator creates an AyncTask which in turn invokes displayData in PackagePopulator. But it never happens and the activity gets stuck. What am I doing wrong here.

public class PackagePopulator implements ServerDataProcessor {

    private CountDownLatch counter=new CountDownLatch(1);
    String[]  packages;

    public void getPagesFromServer() {
        new BackgroundDataPopulator(IMgrApplication.getAppContext().getString(R.string.list),new PData(),this).execute();

    }

    public String[] getPages() {
        try {

            counter.await();
        } catch (InterruptedException e) {
            packages=new String[0];
        }
        return packages;
    }

    @Override
    public void displayData(ServerOutput output) {


        Page[] pgArray = new Page[((PageData)output).getPages().size()];
        pages=new String[pgArray.length];
        pgArray = ((PageData)output).getPages().toArray(pgArray);
        for(int i=0;i<pgArray.length;i++){
            pages[i]=pgArray[i].getName();
        }
        counter.countDown();

    }

}





public class BackgroundDataPopulator extends AsyncTask<Void, String, ServerOutput> {
    // connector=new JSONConnector();
    Connector connector;
    String curUrl;
    ServerOutput curServerOutput;
    ServerDataProcessor processor;


    public BackgroundDataPopulator(String url, ServerOutput serverOutput,ServerDataProcessor curProcessor) {
        //connector = new UnitTestConnector();
        connector = new JSONConnector();
        curUrl = url;
        curServerOutput = serverOutput;
        processor=curProcessor;
    }

    @Override
    protected ServerOutput doInBackground(Void... params) {

        return connector.getData(URLUtils.getFormattedUrl(curUrl),curServerOutput);
    }

    @Override
    protected void onPostExecute(ServerOutput output) {
        processor.displayData(output);
        //Toast.makeText(BaseFragmentActivity.this, "Done!",Toast.LENGTH_SHORT).show();
    }
}




protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    pagePopulator=new PagePopulator();
    pagePopulator.getPagesFromServer();
    super.onCreate(savedInstanceState);

}

public ArrayAdapter<CharSequence> getSpinnerDataArray(String item) {
    return new ArrayAdapter<CharSequence>(this,android.R.layout.simple_spinner_item,pagePopulator.getPages());
}
sab
  • 9,767
  • 13
  • 44
  • 51

1 Answers1

1

It is not clear what exactly you are doing and where the AscynTask is being started. It looks like you are calling await() and countDown() on the same thread and that is why you are getting blocked. Post more details and/or debug your code.

Nikolay Elenkov
  • 52,576
  • 10
  • 84
  • 84
  • I modified code a bit to add execute for backgroundtask. But to answer your question, displayData is being invoked by AsyncTask thread created in onCreate method – sab May 21 '12 at 03:06
  • Who and when is calling `PackagePopulator.getPages()`? – Nikolay Elenkov May 21 '12 at 03:12
  • That is called by the activity which uses PackagePopulator to get data from server, I edited code above – sab May 21 '12 at 03:17
  • I still don't see any calls to `PackagePopulator.getPages()`. In any case, does `doInBackground()` get executed at all? – Nikolay Elenkov May 21 '12 at 03:28
  • That was a typo, its getting called in getSpinnerDataArray above, also doInBackground gets called but not onPostExecute – sab May 21 '12 at 03:37
  • What are you trying to do? Your use of `CountdownLatch` doesn't make sense (at least to me). As for why it blocks, you are calling `await()` on the UI thread, and then `countDown()` is supposed to be called on the UI thread as well. Obviously this is not going to work. – Nikolay Elenkov May 21 '12 at 03:46
  • Ok that could be the problem. I want my UI thread to wait when calling getPages if the data is not yet downloaded from server – sab May 21 '12 at 03:58
  • You shouldn't block the UI thread, _ever_. Just display a progress dialog or something and when the data is downloaded (or an error occurs), `onPostExecute()` will be called and you can update your UI accordingly. You don't need the `CountdownLatch` for this, just `AsyncTask`. – Nikolay Elenkov May 21 '12 at 04:15