启用Proguard NoSuchMethodException。

问题描述 投票:0回答:1

如果我不启用Proguard,就不会出现这个问题。

buildTypes {
    release {
        minifyEnabled true
        shrinkResources true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}

Logcat:

java.lang.RuntimeException: java.lang.NoSuchMethodException: com.example.NewUsers$f.<init> [class android.view.View]
    at i.c.a.b.f.b(:147)
    at androidx.recyclerview.widget.RecyclerView$g.a(:7078)
    at androidx.recyclerview.widget.RecyclerView$v.a(:6235)
    at androidx.recyclerview.widget.RecyclerView$v.b(:6118)
    at androidx.recyclerview.widget.RecyclerView$v.d(:6114)
    at androidx.recyclerview.widget.LinearLayoutManager$c.a(:2303)
    at androidx.recyclerview.widget.LinearLayoutManager.a(:1627)
    at androidx.recyclerview.widget.LinearLayoutManager.a(:1587)
    at androidx.recyclerview.widget.LinearLayoutManager.c(:665)
    at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(:4134)
    at androidx.recyclerview.widget.RecyclerView.dispatchLayout(:3851)
    at androidx.recyclerview.widget.RecyclerView.consumePendingUpdateOperations(:1897)
    at androidx.recyclerview.widget.RecyclerView$a.run(:414)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:996)
    at android.view.Choreographer.doCallbacks(Choreographer.java:794)
    at android.view.Choreographer.doFrame(Choreographer.java:725)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:981)
    at android.os.Handler.handleCallback(Handler.java:883)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:237)
    at android.app.ActivityThread.main(ActivityThread.java:7807)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1047)
 Caused by: java.lang.NoSuchMethodException: com.example.NewUsers$f.<init> [class android.view.View]
    at java.lang.Class.getConstructor0(Class.java:2332)
    at java.lang.Class.getConstructor(Class.java:1728)
    at i.c.a.b.f.b(:144)
    at androidx.recyclerview.widget.RecyclerView$g.a(:7078) 
    at androidx.recyclerview.widget.RecyclerView$v.a(:6235) 
    at androidx.recyclerview.widget.RecyclerView$v.b(:6118) 
    at androidx.recyclerview.widget.RecyclerView$v.d(:6114) 
    at androidx.recyclerview.widget.LinearLayoutManager$c.a(:2303) 
    at androidx.recyclerview.widget.LinearLayoutManager.a(:1627) 
    at androidx.recyclerview.widget.LinearLayoutManager.a(:1587) 
    at androidx.recyclerview.widget.LinearLayoutManager.c(:665) 
    at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(:4134) 
    at androidx.recyclerview.widget.RecyclerView.dispatchLayout(:3851) 
    at androidx.recyclerview.widget.RecyclerView.consumePendingUpdateOperations(:1897) 
    at androidx.recyclerview.widget.RecyclerView$a.run(:414) 
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:996) 
    at android.view.Choreographer.doCallbacks(Choreographer.java:794) 
    at android.view.Choreographer.doFrame(Choreographer.java:725) 
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:981) 
    at android.os.Handler.handleCallback(Handler.java:883) 
    at android.os.Handler.dispatchMessage(Handler.java:100) 
    at android.os.Looper.loop(Looper.java:237) 
    at android.app.ActivityThread.main(ActivityThread.java:7807) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1047) 

当前proguard:

-keep class com.example.models.** { *; }

Java类。

public class NewUsers extends AppCompatActivity {

    ....

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_users);

        ....

        mNewUsersList = findViewById(R.id.newUsers);
        mNewUsersList.setHasFixedSize(true);
        mNewUsersList.setLayoutManager(new LinearLayoutManager(this));

        onStart();

    }

    @Override
    protected void onStart() {
        super.onStart();
        FirebaseRecyclerAdapter<Users, UsersViewHolder> adapter = new FirebaseRecyclerAdapter<Users, UsersViewHolder>(
                Users.class,
                R.layout.users_list,
                UsersViewHolder.class,
                mDatabaseReference
        ) {

            @Override
            protected void populateViewHolder(UsersViewHolder usersViewHolder, Users users, int position) {
                usersViewHolder.setName(users.getName());

            }
        };
        mNewUsersList.setAdapter(adapter);
    }

    public static class UsersViewHolder extends RecyclerView.ViewHolder {
        View mView;

        public UsersViewHolder(@NonNull View itemView) {
            super(itemView);
            mView = itemView;
        }

        public void setName(String name) {
            TextView mUserNameView = mView.findViewById(R.id.textViewUserName);
            mUserNameView.setText(name);
        }
    }
}

是否有任何可能性,我只是想启用minify和收缩的版本

模型。

public class Users {

    String name;

    public Users() {
    }

    public Users(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}
android firebase android-recyclerview proguard firebaseui
1个回答
3
投票

检查这个日志。

java.lang.RuntimeException: java.lang.NoSuchMethodException: com.example.NewUsers$f.<init> [class android.view.View]

正确的proguard规则将是:'..:

-keep class com.example.** { *; }

另外,请注意,这将排除com.example下的所有类,我建议把数据类移到一个公共目录下,并混淆那个完整的目录。


0
投票

你的类的包是 com.example 但proguard规则是为 com.example.models. 修改后应该可以解决这个问题。


0
投票

解决方案1:

把你的保留类从 com.example.modelcom.example.

更好的解决办法

如果你在使用这个类的文件中正确地导入了这个类,并且没有使用任何形式的反射,proguard应该不会删除这个类。

试着把它放在一个普通的位置,在那里你可能不需要使用反射或间接方法来访问这个类。


0
投票

java.lang.RuntimeException: java.lang.NoSuchMethodException: com.example.NewUsers$f. 在i.c.a.b.f.b(:147)处出现[类android.view.View]。

当找不到特定的方法时,会抛出上述异常。这里是由于proguard的原因。你应该尝试用

-keep class com.example.** { *; }
-keepclassmembers class com.example.** { *; }

增加 @Keep 在整个包上添加它可以保持整个类的原样。将它添加到一个方法或字段上,将保持方法字段(和它的名字)以及类名不变。

OP将是

public class HomeActivity extends AppCompatActivity { 

private TextView f2032b; 
private Button f2033c; 

顺便说一下

您可以通过在您项目的 gradle.properties 文件。

android.enableR8.fullMode=true

它可能需要你加入额外的ProGuard规则以避免运行时的问题。请阅读官方指南,了解 Enable more aggressive optimizations

© www.soinside.com 2019 - 2024. All rights reserved.