简体   繁体   中英

How to refer to a result of AsyncTask in another class?

I have 2 classes: FeedItem and imgDownloader. In the second one I'm scraping url to an image and in the first one I'm making a method setLink, to assign it and display via Picasso in my app.

Fragment of feedItem.class:

public class feedItem {
    String link;

public void setLink(String link) {

    imgDownload task = new imgDownload();
    String urlx = task...;  //Here should be a result of that AsyncTask's doInBackground
    this.link = urlx;
}
}

imgDownload.class:

public class imgDownload extends AsyncTask<String, String, String> {

    feedItem item = new feedItem();
    String url = item.getLink();
    String imglink;

    @Override
    protected String doInBackground(String... params) {
        Document doc = null;
        try {
            doc = Jsoup.connect(url).get();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        Element masthead = doc.select("div.post-image").select("img[src~=(?i)\\.(png|jpe?g)]").first();
        url = masthead.absUrl("src");
        return url;
    }
    @Override
    protected void onPostExecute(String result) {
        imglink = result; //Result of doInBackground
    }
}

I read almost all similar question to this, but after 2 days od studying I still don't know how to do it properly so I need a concrete answer how to make it.

//////////EDIT

So I used that Callbacks, and I get various errors, like that:

                                                                 --------- beginning of crash
06-27 23:57:14.446 3274-3321/pl.dariusz.app E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
                                                            Process: pl.dariusz.app, PID: 3274
                                                            java.lang.RuntimeException: An error occurred while executing doInBackground()
                                                                at android.os.AsyncTask$3.done(AsyncTask.java:309)
                                                                at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
                                                                at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
                                                                at java.util.concurrent.FutureTask.run(FutureTask.java:242)
                                                                at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
                                                                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                                at java.lang.Thread.run(Thread.java:818)
                                                             Caused by: java.lang.IllegalArgumentException: Must supply a valid URL
                                                                at org.jsoup.helper.Validate.notEmpty(Validate.java:102)
                                                                at org.jsoup.helper.HttpConnection.url(HttpConnection.java:72)
                                                                at org.jsoup.helper.HttpConnection.connect(HttpConnection.java:36)
                                                                at org.jsoup.Jsoup.connect(Jsoup.java:73)
                                                                at pl.dariusz.app.imgDownloader.doInBackground(imgDownloader.java:30)
                                                                at pl.dariusz.app.imgDownloader.doInBackground(imgDownloader.java:12)
                                                                at android.os.AsyncTask$2.call(AsyncTask.java:295)
                                                                at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
                                                                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
                                                                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
                                                                at java.lang.Thread.run(Thread.java:818) 

06-27 23:57:14.533 3274-3302/pl.dariusz.app I/Process: Sending signal. PID: 3274 SIG: 9

You need to create a callback which your AsyncTask can use to send data to its calling Activity.

A simple interface that can take the Strings from the AsyncTask should suffice.

You can find a very simple example of this method passing images in my Learn Android repository.

Add constructor for the Async task with parameter your desired property. Something like that:

public class ImgDownload extends AsyncTask<String, String, String> {

    feedItem item = new feedItem();
    String url = item.getLink();
    String imglink;

    public ImgDownload(String link){
         imglink = link;
    } 

    @Override
    protected String doInBackground(String... params) {
        Document doc = null;
        try {
            doc = Jsoup.connect(params[0]).get();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        Element masthead = doc.select("div.post-image").select("img[src~=(?i)\\.(png|jpe?g)]").first();
        url = masthead.absUrl("src");
        return url;
    }
    @Override
    protected void onPostExecute(String result) {
        imglink = result; //Result of doInBackground
    }
}

and call this async task like:

public class feedItem {
    String mLink;

    public void setLink(String rawLink) {
        imgDownload task = new imgDownload(mLink);
        task.execute(rawLink);
    }
}

More: Тhis solutions is ugly. Its works, but its not flexible. You can create an interface that you can use for callback. Take a look here . Its exactly the right way.

 imgDownload task = new imgDownload();
 String result = task.execute().get; // result is the output from onPostExecute.

I wrote up a complete guide of how to do it here: https://stackoverflow.com/a/36166643/3962091

The general process is to put your AsyncTask in its own class file, and declare a callback interface within the AsyncTask to which you will send results. Then any other class (including an Activity ) can simply implement the callback interface to get any results the AsyncTask has to offer.

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