質問

I have an application which needs to make repeated calls to a web API. Effectively, it iterates over records in a SQL table and makes a unique call out to the web server with the appropriate data. It's a kind of data synchronization.

As I understand it, when performing this kind of HTTP request to an API it should occur within an AsyncTask to avoid hanging up the UI, so I have made my AsyncTask class which makes a request and parses back the response, but I need to pass this data back to the calling class.

On top of that, I don't want the calling class to run these requests in parallel. I want it to make one request, and not iterate to the next record in the table and make a second request until that first request finishes. So in a way, I want this to be blocking, but still in a separate thread so the UI doesn't freeze up. At least, I think this is what I want.

Pseudo code is something along the lines of this:

// caller function
public void synchronize(){
    load all records from sql table
    for each record:
        if record type is X:
            new asyncX().execute(record)
            // once this completes successfully, 
            // I want to do something with the return value here, 
            // before going on to the next iteration
            // 
            // and eventually when there is some UI here, 
            // show some nice spinny logo and maybe some text for 
            // what's going on right now
        if record type is Y:
            new asyncY().execute(record)
            // same as above
}

// Async class
public class asyncX extends AsyncTask<RecordType,Void,RecordType> {
    protected RecordType doInBackground(RecordType... record) {
        convert record to json
        make http request
        receive http response
        parse response
        return record
    }
}

The way I'm thinking of doing this is changing the synchronize function to only run one record at a time, call the async task, and end, and then the async task calls back to a synchronize_followup() function which does what it needs to do with the return value, and then starts synchronize back up again, but I'm not sure I like that.

Thoughts on how to proceed?

役に立ちましたか?

解決 2

To meet my needs, I instead made the synchronize functionality into an AsyncTask, spun that off from my UI thread, and left the outgoing HTTP request as regular functions (and as such, they block).

This means that the synchronization process happens in the background, does not affect the UI thread, and each outgoing API call happens sequentially.

他のヒント

The way you want to handle this is already invented with threading sychronization, so you don't have to implement it your way.

There's a class similar to Semaphore called CountDownLatch. When you declare an object, and activate the lock mechanism via .wait(), it will freeze execution of further code until you issue a .countDown() statement. Indeed, if you declare a CountDownLatch(1) will probably make the effect you're looking for.

On the CountDownLatch's reference page there's a nice example on how to implement this by blocking one Thread's execution depending on the execution of other.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top