我试图用retrolambda沿gradle这个-retrolambda插件.一般来说它工作正常,但是当我编译发布时,该lint阶段失败,异常:
:playground.dagger:lintVitalReleaseFailed converting ECJ parse tree to Lombok for file D:\....\playground\dagger\MainActivity.java
java.lang.UnsupportedOperationException: Unknown ASTNode child: LambdaExpression
at lombok.ast.ecj.EcjTreeVisitor.visitOther(EcjTreeVisitor.java:368)
at lombok.ast.ecj.EcjTreeVisitor.visitEcjNode(EcjTreeVisitor.java:364)
at lombok.ast.ecj.EcjTreeConverter.visit(EcjTreeConverter.java:295)
at lombok.ast.ecj.EcjTreeConverter.toTree(EcjTreeConverter.java:236)
at lombok.ast.ecj.EcjTreeConverter.fillList(EcjTreeConverter.java:282)
at lombok.ast.ecj.EcjTreeConverter.fillList(EcjTreeConverter.java:252)
at lombok.ast.ecj.EcjTreeConverter.access$100(EcjTreeConverter.java:141)
at lombok.ast.ecj.EcjTreeConverter$2.visitMessageSend(EcjTreeConverter.java:1042)
at lombok.ast.ecj.EcjTreeVisitor.visitEcjNode(EcjTreeVisitor.java:156)
at lombok.ast.ecj.EcjTreeConverter.visit(EcjTreeConverter.java:295)
at lombok.ast.ecj.EcjTreeConverter.toTree(EcjTreeConverter.java:236)
at lombok.ast.ecj.EcjTreeConverter.fillList(EcjTreeConverter.java:282)
at lombok.ast.ecj.EcjTreeConverter.fillList(EcjTreeConverter.java:252)
at lombok.ast.ecj.EcjTreeConverter.toBlock(EcjTreeConverter.java:397)
at lombok.ast.ecj.EcjTreeConverter.access$1500(EcjTreeConverter.java:141)
at lombok.ast.ecj.EcjTreeConverter$2.visitMethodDeclaration(EcjTreeConverter.java:1241)
at lombok.ast.ecj.EcjTreeVisitor.visitEcjNode(EcjTreeVisitor.java:152)
at lombok.ast.ecj.EcjTreeConverter.visit(EcjTreeConverter.java:295)
at lombok.ast.ecj.EcjTreeConverter.toTree(EcjTreeConverter.java:236)
at lombok.ast.ecj.EcjTreeConverter.fillList(EcjTreeConverter.java:282)
at lombok.ast.ecj.EcjTreeConverter.fillList(EcjTreeConverter.java:252)
at lombok.ast.ecj.EcjTreeConverter.access$100(EcjTreeConverter.java:141)
at lombok.ast.ecj.EcjTreeConverter$2.createNormalTypeBody(EcjTreeConverter.java:563)
at lombok.ast.ecj.EcjTreeConverter$2.visitTypeDeclaration(EcjTreeConverter.java:486)
at lombok.ast.ecj.EcjTreeVisitor.visitEcjNode(EcjTreeVisitor.java:48)
at lombok.ast.ecj.EcjTreeConverter.visit(EcjTreeConverter.java:295)
at lombok.ast.ecj.EcjTreeConverter.toTree(EcjTreeConverter.java:236)
at lombok.ast.ecj.EcjTreeConverter.fillList(EcjTreeConverter.java:282)
at lombok.ast.ecj.EcjTreeConverter.fillList(EcjTreeConverter.java:252) …Run Code Online (Sandbox Code Playgroud) 我们知道匿名类维护对其封闭实例的引用,这可能导致Android上下文泄漏.
由于retrolambda backports中的lambda表达式来Java7,它可能是值得一试.
似乎 Java8 lambdas没有这个问题,但我找不到任何官方信息.
任何线索?
我已经建立了一个非常简单的项目来测试Robolectric + Data Binding + Retrolambda的集成.当我运行测试套装时,我收到以下消息:
Error:(30, 30) Gradle: error: cannot access AndroidHttpClient
class file for android.net.http.AndroidHttpClient not found
Run Code Online (Sandbox Code Playgroud)
这很奇怪,因为我不在任何地方使用AndroidHttpClient.
此处发生错误,在"活动"行:
@Before
public void setup() {
activity = Robolectric.setupActivity(MainActivity.class); // Error on this line
textView = (TextView) shadowOf(activity).findViewById(R.id.textView);
button = (Button) activity.findViewById(R.id.button);
editText = (EditText) activity.findViewById(R.id.editText);
}
Run Code Online (Sandbox Code Playgroud)
该程序从不使用AndroidHttpClient.事实上,这是整个计划:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setUser(new User());
binding.button.setOnClickListener((v) -> {
binding.textView.setText(String.format("Hello, %s!", binding.editText.getText()));
binding.editText.setText("");
});
}
Run Code Online (Sandbox Code Playgroud)
关于什么是错的想法?
有没有办法禁用警告
Jack需要支持java 8语言功能.
使用Retrolambda时?
我现在不想要杰克支持,因为它还没有编译我们的项目.
我可以使用retrolambda来启用Android API级别<24的lambdas.这样可行
myButton.setOnClickListener(view -> Timber.d("Lambdas work!"));
Run Code Online (Sandbox Code Playgroud)
这也有效
Runnable runLater = () -> Timber.d("Lambdas work!");
runLater.run();
Run Code Online (Sandbox Code Playgroud)
但是这个没有
Consumer<Integer> runLaterWithInt = (Integer i) -> Timber.d("i = " + i);
runLaterWithInt.accept(3);
Run Code Online (Sandbox Code Playgroud)
最后一个适用于Android API Level 24,但在其他设备上,此代码会导致崩溃
java.lang.NoClassDefFoundError: com.retrolambdatry.MainActivity$$Lambda$1
Run Code Online (Sandbox Code Playgroud)
我试图启用Java 8.而不是使用retrolambda.前两个代码示例仍然有效,尽管butterknife停止工作.https://developer.android.com/preview/j8-jack.html#configuration这里ava.util.function被认为是支持的,但在运行第三个时,我仍然得到一个崩溃,这一次却是有一点不同
java.lang.NoClassDefFoundError: com.retrolambdatry.MainActivity$-void_onCreate_android_os_Bundle_savedInstanceState_LambdaImpl1
Run Code Online (Sandbox Code Playgroud) 在我的项目中,我使用的是受欢迎的图书馆retrolambda.我刚刚下载了新的Android Studio 3.0 Canary 1.
我已经更新了我的项目以使用Gradle等新版本.一切都很好.
Android Studio 3中的新功能是为了支持某些Java8功能而构建的.新的AS3建议删除retrolambda并使用这些功能.
我删除了retrolambda,Gradle构建成功但是应用程序崩溃了这个错误(在有lambda的地方)
E/UncaughtException: java.lang.NoSuchMethodError: No static method lambda$replace$2
Run Code Online (Sandbox Code Playgroud)
我在我的项目中使用RxJava2.我不确定这与它有关,但在我看来,Java8的内置功能看起来不起作用.也许我需要在"某个地方"设置一些东西?
我的Gradle文件
根项目
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0-alpha1'
classpath 'com.google.gms:google-services:3.0.0'
//classpath 'me.tatarka:gradle-retrolambda:3.6.1'
}
Run Code Online (Sandbox Code Playgroud)
应用模块
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.jakewharton.hugo:hugo-plugin:1.2.1'
classpath 'com.jakewharton:butterknife-gradle-plugin:8.5.1'
}
}
repositories {
mavenCentral()
maven { url "https://jitpack.io" }
}
apply plugin: 'com.android.application'
apply plugin: 'com.jakewharton.hugo'
...
compile 'com.android.support:multidex:1.0.1'
compile 'com.google.firebase:firebase-analytics:9.8.+'
compile 'com.google.firebase:firebase-crash:9.8.+'
compile 'com.google.android.gms:play-services-maps:9.8.+'
compile 'com.google.android.gms:play-services-analytics:9.8.+'
compile 'com.google.android.gms:play-services-auth:9.8.+'
compile 'com.github.PhilJay:MPAndroidChart:v3.0.1'
//Support Library
(...)
compile …Run Code Online (Sandbox Code Playgroud) 我在我的Android项目中使用Java 8.我已经设置了Jack(在Android应用程序模块中)和Retrolambda(在其他模块中).
我遇到的问题是当我尝试使用类变量(并且我可以在任何模块中重现它)时,我的Lambda表达式在一个特定场景中崩溃,在所有其他情况下,它按预期工作.也许这是标准的Java行为,但到目前为止我找不到任何解释.有谁知道问题在哪里?我的班级和崩溃如下:
public class LambdaBugTest {
private final String parentClassVariableString = "parentClassVariableString";
public void testLambdas() {
// ----------- THESE WORK OK --------------
final Functional simpleLambdaWorks = text -> System.out.print(text);
final Functional methodReferenceWorks = System.out::print;
final Functional interfaceWithClassParamWorks = new Functional() {
@Override
public void doSomething(String text) {
System.out.print(text + " " + parentClassVariableString);
}
};
// -----------------------------------------
// ----------- THIS ONE CRASHES ------------
final Functional lambdaWithClassParamCrashes = text -> System.out.print(text + " " + parentClassVariableString);
// -----------------------------------------
simpleLambdaWorks.doSomething("Text from …Run Code Online (Sandbox Code Playgroud) 我想运行2个异步任务,一个跟随另一个(顺序).我读过有关ZIP或Flat的内容,但我对此并不了解......
我的目的是从本地SQLite加载数据,当它完成时,它将查询调用到服务器(远程).
有人可以建议我,一种实现这一目标的方法吗?
这是我正在使用的RxJava Observable骨架(单个任务):
// RxJava Observable
Observable.OnSubscribe<Object> onSubscribe = subscriber -> {
try {
// Do the query or long task...
subscriber.onNext(object);
subscriber.onCompleted();
} catch (Exception e) {
subscriber.onError(e);
}
};
// RxJava Observer
Subscriber<Object> subscriber = new Subscriber<Object>() {
@Override
public void onCompleted() {
// Handle the completion
}
@Override
public void onError(Throwable e) {
// Handle the error
}
@Override
public void onNext(Object result) {
// Handle the result
}
};
Observable.create(onSubscribe)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
Run Code Online (Sandbox Code Playgroud) 我正在使用改造,我觉得rxjava(with retrolambda)非常适合以下流程:
为每个小部件
a)获取给定窗口小部件类型的文章列表(http)
b)将所有文章保存到db
c)获取列表中的第一篇(最新)文章并使用本文中的适当值更新widget.articleName和widget.articleUrl
但是我不确定在步骤2a之后该怎么做.到目前为止,这是我的代码
apiService.getWidgets(token)
.flatMapIterable(widgets -> widgets)
.flatMap(widget -> apiService.getArticles(token, widget.type))
...
.toList()
.subscribe(
modifiedWidgets -> saveWidgets(modifiedWidgets),
throwable -> processWidgetError(throwable)
);
Run Code Online (Sandbox Code Playgroud)
我玩过一些操作员,但是当链接时,我似乎总是缩小范围(例如,获取单个文章的句柄),然后再也无法访问原始小部件进行修改.
@GET("/widgets")
Observable<List<Widget>> getWidgets(@Header("Authorization") String token);
@GET("/articles")
Observable<List<Article>> getArticles(@Header("Authorization") String token, @Query("type") String type);
Run Code Online (Sandbox Code Playgroud) 在我们的项目中,我们使用gradle + retrolambda + proguard.Retrolambda增量构建设置为false.
有时构建传递没有错误,但源代码更改不适用于应用程序.为了解决这个问题,我们用它来清理和重建项目
gradlew clean assembleDebug
Run Code Online (Sandbox Code Playgroud)
但在我们的情况下,它需要约2.30米.那太久了.
我们如何解决这个问题?
retrolambda ×10
android ×9
lambda ×3
java-8 ×2
rx-java ×2
android-lint ×1
data-binding ×1
java ×1
lint ×1
observable ×1
proguard ×1
retrofit ×1
robolectric ×1
subscriber ×1