Search code examples
androidfirebaseandroid-recyclerviewproguardfirebaseui

Proguard enabled NoSuchMethodException


I'm not getting this issue, If I do not enable Proguard like this:

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) 

Current proguard:

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

Java class:

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);
        }
    }
}

Is there any possibilities, I just want to enable minify and shrink for release

Model:

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;
    }

}

Solution

  • Check this log:

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

    The correct pro guard rule will be:

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

    Also, note that this will exclude all classes under com.example, I suggest moving the data classes to a common directory and obfuscate that complete directory.