修复Android更新AGP8后retrofit2混淆出现错误:Unable to create call adapter for interface retrofit2.Call,并附上完整混淆规则

Android更新AGP8后retrofit2混淆出现错误

背景

由于项目需要适配安卓14,将AGP升级到了8.2.2,并将Gradle升级到了8.2。最终代码混淆出现了很多问题,其中retrofit2的报错如下:

 Caused by: java.lang.IllegalArgumentException: Unable to create call adapter for interface retrofit2.Call
     for method HttpBinService.get
     at retrofit2.Utils.methodError(Utils.java:55)
     at retrofit2.HttpServiceMethod.createCallAdapter(HttpServiceMethod.java:116)
     at retrofit2.HttpServiceMethod.parseAnnotations(HttpServiceMethod.java:67)
     at retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:39)
     at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:208)
     at retrofit2.Retrofit$1.invoke(Retrofit.java:166)
     at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
     at $Proxy3.get(Unknown Source)
     at io.vibin.myapplication.MainActivity.onCreate(MainActivity.kt:45)
     at android.app.Activity.performCreate(Activity.java:8290)
     at android.app.Activity.performCreate(Activity.java:8269)
     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1384)
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3657)
     ... 12 more
 Caused by: java.lang.IllegalArgumentException: Call return type must be parameterized as Call<Foo> or Call<? extends Foo>
     at retrofit2.DefaultCallAdapterFactory.get(DefaultCallAdapterFactory.java:42)
     at retrofit2.Retrofit.nextCallAdapter(Retrofit.java:259)
     at retrofit2.Retrofit.callAdapter(Retrofit.java:243)
     at retrofit2.HttpServiceMethod.createCallAdapter(HttpServiceMethod.java:114)
     ... 23 more

经研究发现,原因是在AGP7.2以上的版本默认开启了R8完整模式。R8完整模式对未保留的类剥离通用签名。因此需要在proguard-rules.pro中配置额外的混淆规则规避这些问题,另外也可以通过在gradle.properties中添加android.enableR8.fullMode=false关闭R8完整模式。

需要新增的规则

 # 使用R8全模式,对未保留的类剥离通用签名。挂起函数被包装在使用类型参数的continuation中。
 -keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation 
  
 # 如果不保留,R8完整模式将从返回类型中剥离通用签名。
 -if interface * { @retrofit2.http.* public *** *(...); } 
 -keep,allowoptimization,allowshrinking,allowobfuscation class <3> 
  
 # 在R8全模式下,对未保留的类剥离通用签名。
 -keep,allowobfuscation,allowshrinking class retrofit2.Response 

另外附上通用的对Retrofit2 , Rxjava2 , Okhttp3混淆规则,这里参考大佬的文章:AndroidStudio混淆打包踩坑之retrofit2.

注意,这里只是通用配置不包含R8完整模式的额外配置,请根据需求自己调整!

## ---------Retrofit混淆方法---------------
-dontwarn javax.annotation.**
-dontwarn javax.inject.**
# OkHttp3
-dontwarn okhttp3.logging.**
-keep class okhttp3.internal.**{*;}
-dontwarn okio.**
# Retrofit
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
# RxJava RxAndroid
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
    long producerIndex;
    long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
    rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
    rx.internal.util.atomic.LinkedQueueNode consumerNode;
}

# Gson
-keep class com.google.gson.stream.** { *; }
-keepattributes EnclosingMethod

# Gson
-keep class com.demo.demo1.service.bean.**{*;} # 自定义数据模型的bean目录

至此问题已解决,如有其它问题欢迎大佬补充。

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
根据提供的引用内容,可以看出这是一个Android编程的问题,需要使用Bundle传递对象。在这个问题中,需要创建一个Person类,该类需要实现Serializable接口,以便在不同的Activity之间传递。在HobbyActivity中,需要创建一个ArrayList<Person>泛型集合,保存四个Person类的对象,并使用ListView显示姓名。当单击姓名时,需要进入MessageActivity,显示姓名、年龄和爱好。最终结果应该显示BMI计算器张三李四王五赵权。 具体步骤如下: 1. 创建Person类,该类需要实现Serializable接口,以便在不同的Activity之间传递。 2. 在HobbyActivity中,创建一个ArrayList<Person>泛型集合,保存四个Person类的对象,并使用ListView显示姓名。 3. 当单击姓名时,使用Intent传递该Person对象到MessageActivity中。 4. 在MessageActivity中,获取传递过来的Person对象,并显示姓名、年龄和爱好。 代码示例: 1. Person类的定义: ``` public class Person implements Serializable { private String name; private int age; private String hobby; public Person(String name, int age, String hobby) { this.name = name; this.age = age; this.hobby = hobby; } public String getName() { return name; } public int getAge() { return age; } public String getHobby() { return hobby; } } ``` 2. 在HobbyActivity中,创建ArrayList<Person>泛型集合,并使用ListView显示姓名: ``` ArrayList<Person> personList = new ArrayList<>(); personList.add(new Person("张三", 20, "篮球")); personList.add(new Person("李四", 22, "足球")); personList.add(new Person("王五", 25, "乒乓球")); personList.add(new Person("赵权", 18, "羽毛球")); ListView listView = findViewById(R.id.listView); ArrayAdapter<Person> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, personList); listView.setAdapter(adapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent intent = new Intent(HobbyActivity.this, MessageActivity.class); intent.putExtra("person", personList.get(position)); startActivity(intent); } }); ``` 3. 在MessageActivity中,获取传递过来的Person对象,并显示姓名、年龄和爱好: ``` TextView nameTextView = findViewById(R.id.nameTextView); TextView ageTextView = findViewById(R.id.ageTextView); TextView hobbyTextView = findViewById(R.id.hobbyTextView); Intent intent = getIntent(); Person person = (Person) intent.getSerializableExtra("person"); nameTextView.setText(person.getName()); ageTextView.setText(String.valueOf(person.getAge())); hobbyTextView.setText(person.getHobby()); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值