23

How do you face nested callbacks in Android? For example, in my app I use Locations API and then, when I have the current lat-lng, I do an HTTP request to my server. In this situation I have two nested callbacks. It's no so bad, but what If I had three or more? I've read about it in this question but I wonder if there are something like Promises for Android.

All I've found is this. Someone knows more about the subject?

Community
  • 1
  • 1
Marcos
  • 4,643
  • 7
  • 33
  • 60
  • 5
    Sure https://github.com/jdeferred/jdeferred , but take note that without Java 8 functional interface syntax, this looks really really ugly. Promises being a concept taken from functional programming that is. – Benjamin Gruenbaum Apr 19 '14 at 00:08

3 Answers3

24

There is something pretty similar already available as part of the Java language, and supported by Android: java.util.concurrent.Future. Perhaps it is good enough for your needs.

By the way, Java 8, which Android does not yet support, has a variant called CompletableFuture that is even closer to a Promise.

cybersam
  • 63,203
  • 6
  • 53
  • 76
  • Thanks. Now, this is used in real development? I've seen the source code for iosched and others Android apps but I've never heard of Promises. – Marcos Apr 19 '14 at 09:38
  • Yes, Future is used quite a bit. Here is a tutrial that might be helpful: http://java.dzone.com/articles/javautilconcurrentfuture – cybersam Apr 19 '14 at 19:37
  • 5
    [CompletableFuture](https://developer.android.com/reference/java/util/concurrent/CompletableFuture.html) was added in Android 7 (API level 24) – Stefan Frye Oct 08 '16 at 09:24
  • Java 8 is partially supported (not Jack) https://developer.android.com/studio/write/java8-support.html – user221256 Feb 01 '18 at 20:01
  • 1
    "There is something pretty similar already available as part of the Java language, and supported by Android: java.util.concurrent.Future.") Futures really aren't too similar to Promises. While Promises are callback-based, Futures are usually waitet for synchronously. – MarkusM May 08 '18 at 06:15
  • Remember you can use the backported `CompletableFuture` that's made specifically for Android if you want to support older devices. Check out: https://github.com/retrostreams/android-retrofuture – rickchristie Feb 28 '21 at 12:30
6

As of 2020, android has support for CompletableFuture, Java's answer to Javascript promises: https://developer.android.com/reference/java/util/concurrent/CompletableFuture

If that is not possible for your app's android api level, then see https://github.com/retrostreams/android-retrofuture .

Example:

CompletableFuture.supplyAsync(()->{
            String result = somebackgroundFunction();
            return result;
        }).thenAcceptAsync(theResult->{
            //process the result
        }).exceptionallyCompose(error->{
            ///process the error
            return CompletableFuture.failedFuture(error);
        });

To handle the result and update the UI, you need to specify main thread executor:

        CompletableFuture.supplyAsync(()->{
            String result = somebackgroundFunction();
            return result;
        }).thenAcceptAsync(theResult->{
            //process the result
        }, ContextCompat.getMainExecutor(context))
                .exceptionallyComposeAsync(error->{
            ///process the error
            return CompletableFuture.failedFuture(error);
        }, ContextCompat.getMainExecutor(context));
Kidogo
  • 161
  • 1
  • 8
  • A link to a solution is welcome, but please ensure your answer is useful without it: [add context around the link](//meta.stackexchange.com/a/8259) so your fellow users will have some idea what it is and why it’s there, then quote the most relevant part of the page you're linking to in case the target page is unavailable. [Answers that are little more than a link may be deleted.](//stackoverflow.com/help/deleted-answers) – dippas Jun 08 '20 at 09:52
5

This very old post, but, I want to share my problem and solution here.

I has similar problem, I need to perform 4 network task one after another while login to my app and finally when all requests are success opening the landing screen of the app. Initially I used nested callback, but now i found a new android-Promise library https://github.com/crawlinknetworks/android-promise it solved my problem. It is very easy and simple to use.

Following: How it is working?

doSomeTask(int someValue, String extra)
    .then(res -> doSecondTask((MyObject) res))       // res is result form doSomeTask()
    .then(res -> doThirdTask((OtherObject) res)))    // res is result form doThirdTask()
    .then(res -> doFourthTask((int) res)))           // res is result form doThirdTask()
    .then(res -> doFivthTask())
    .then(res -> {
     // Consume result of the previous function
     return true;    // done
    })
    .error(err -> handleError());                       // Incase of any p.reject()
                            // all from above function error will be available here 
PARAMANANDA PRADHAN
  • 1,104
  • 1
  • 14
  • 23
  • how do you make it work I put the Promise.java in app/src and nothing happen – Cesar Vega Feb 02 '18 at 21:48
  • Excelent! like a JS! – HerberthObregon Jun 15 '18 at 07:41
  • It appears from github that you may actually be the original author of this work. As noted by someone else in the "issues" page, the licence was changed from Apache to a more restrictive one in the 2nd commit (which also fixed/added a bunch of things). Was the restricted licence a mistake, or is it no longer available for free use? – chrisbtoo Dec 14 '22 at 21:01