简体   繁体   中英

Update UI widget from onPostExecute() of AsyncTask in another project

So, I want to display an image in an ImageView that is downloaded from a website and saved on the device's file system. The downloading of the image is done by calling a method in another class (in one of my separate library projects). This method, in turn, calls an AsyncTask to do the downloading in another thread. On the post execute of this AsyncTask, I want to set the image for the ImageView. Keep in mind that this separate library is independent of my main app and knows nothing about my UI (and I wish to keep it this way).

I have a method in the UI portion of my code (in a fragment) that sets the image for this ImageView. I'm thinking it would be nice to pass this method to the library method that retrieves the image. That way, when the download is complete, onPostExecute() could call this UI method that I have. The dilemma I'm facing is I don't want any compile-time dependencies for my library that references my UI/ImageView.

Finally, not every time when this AsyncTask is called do I want to do anything in the post execute. In other words, any post execute logic is completely optional.

General Flow:

1) Code in my fragment calls MyLib.saveRemoteFile(url, destinationFilename)

2) MyLib.saveRemoteFile() downloads the image and saves it to a file by way of a thread (via an AsyncTask)

3) As soon as the image is downloaded and saved, I want to set the ImageView.setImageBitmap() using the bitmap from the saved file

I've looked at the Command pattern, but am stuck on how to implement it in this particular scenario. Any tips on this?

Maybe there is another approach that can be used? ( without MyLib.saveRemoteFile() having compile-time dependencies to the UI )?

UI Fragment code snippet:

.
boolean wasSaved = MyLib.saveRemoteFile(url, destinationFilename, true)
.
.
.

Library code snippet (in a different library project) :

public static boolean saveRemoteFile(String url, String filename, boolean overwriteExistingFile)
{
    .
    // code to check if directory exist and creates it if needed, etc, etc...
    .
    .
    .
    new AsyncTask<String, Void, Boolean>() {
        @Override
        protected Boolean doInBackground(String... params)
        {
            // code to download and save image file...
            .
            .
            .
        }

        @Override
        protected void onPostExecute(Boolean result)
        {
            // *** this is where I want to take the ImageView and set its bitmap image.
        }
    }.execute(new String[] {url, filename});

    return retVal;
}

Command pattern

You should be rather implementing Observer pattern and your download library should allow other code to attach listeners and be notified about when certain action is completed/started/whatever. And since you are just being informed that something happened you can have your code that reacts on that notification completely different in every part of your app if you need so.

Design is flawed, library should have provided you Observer design pattern, using which you would have submitted listener reference along with downloading details.

Upon finishing downloading, library using your provided listener would have notified back to you over download process result, reading which you could have taken action easily with UI.

Moreover in your library code saveRemoteFile() spawns a asynctask, return value is irrelevant here as method wont wait until asynctask is executed.

Possible implementation as per above mentioned info.

    // Interface for bserving
    public interface DownloadListsner{
        public void onSuccess(String uri);
        public void onError(String uri);
    }
    // API for submitting download request
    public void saveRemoteFile(String url, String filename,DownloadListsner listener... ){

        ...
    }

    AsyncTask{
        // Upon finish execution
        onPostExecute(){

// Take action
            listener.onSuccess

            or 

            listener.onError
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM