How to use new Android Architecture without using Lambda Expressions?

Viewed 1364

I have followed this tutorial, written directly by google.

The problem, that I currently have, is the line userDao.save(response.body()); inside the UserRepository class.

 private void refreshUser(final String userId) {
        executor.execute(() -> {
            // running in a background thread
            // check if user was fetched recently
            boolean userExists = userDao.hasUser(FRESH_TIMEOUT);
            if (!userExists) {
                // refresh the data
                Response response = webservice.getUser(userId).execute();
                // TODO check for error etc.
                // Update the database.The LiveData will automatically refresh so
                // we don't need to do anything else here besides updating the database
                userDao.save(response.body());
            }
        });
    }

When I try to do that in my Android Studio Version, I get a message which says that Lambda expressions are not supported at this language level.

enter image description here

I am aware of the fact that I can upgrade my Android Studio to support Java 8 like that, BUT- is there an other way to do so? I don't want to upgrade to Java 8 just to use Lambda Expressions.

3 Answers

If you don't want to use Java 8 (which you should reconsider), you can manually replace:

executor.execute(() -> {
    // task...
});

with:

executor.execute(new Runnable() {
    @Override
    public void run() {
        // task...
    }
});

Assuming you want to use lambda, this is a two-option answer based on your AS version

2.3.3 and lower

First you need to enable jack and use Java 8. Note that jack is officially deprecated, but for AS 2.3.3 and lower it's the only option for getting Java 8 (really buggy option though. Lambda can be used in Java 7 (or lower) using a library, described at the end of this post):

android {
    ...
    defaultConfig {
        ...
        jackOptions {
            enabled true
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

3.0 (beta when writing this) and above

AS 3.0 supports java 8 without needing to activate Jack. So all you need is:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

Assuming you have Java 8 installed, you can now use lambda.

The other workaround (if you can't get Java 8 to compile or don't want to deal with jack or some completely other reason) is as chornge said in his answer to not use lambda or Java 8 and just use the anonymous inner class system.

Alternative

On a side-note, you wrote in your post that you don't want to use Java 8, but use lambda. You can (in theory, haven't tested this myself) use retrolambda. It's a library that adds lambda support for Java <= 7

Related