FirebaseRecyclerAdapter выдает исключение NoSuchMethodException, если сборка выполняется с использованием хранилища ключей Release

Я знаю из https://github.com/firebase/FirebaseUI-Android/issues/46, чтобы исправить NoSuchMethodException :

  1. убедитесь, что ваш класс TaskViewHolder общедоступен
  2. если ваш TaskViewHolder является внутренним классом, например. ваша активность, убедитесь, что она статична

Решение работает, только если я создаю приложение, используя хранилище ключей отладки. Но после того, как я создам приложение с использованием хранилища ключей выпуска, я все еще получаю NoSuchMethodException. минифиенаблед = ложь

Протестировано на Android One Marshmallow Mito A10, Honor 6 и эмуляторе marsmallow.

Ошибка трассировки стека:

Exception java.lang.RuntimeException: java.lang.NoSuchMethodException: <init> [class android.view.View]
com.firebase.ui.database.FirebaseRecyclerAdapter.onCreateViewHolder (FirebaseRecyclerAdapter.java:172)
android.support.v7.widget.RecyclerView$Adapter.createViewHolder (RecyclerView.java:5836)
android.support.v7.widget.RecyclerView$Recycler.getViewForPosition (RecyclerView.java:5060)
android.support.v7.widget.RecyclerView$Recycler.getViewForPosition (RecyclerView.java:4970)
android.support.v7.widget.LinearLayoutManager$LayoutState.next (LinearLayoutManager.java:2029)
android.support.v7.widget.LinearLayoutManager.layoutChunk (LinearLayoutManager.java:1414)
android.support.v7.widget.LinearLayoutManager.fill (LinearLayoutManager.java:1377)
android.support.v7.widget.LinearLayoutManager.onLayoutChildren (LinearLayoutManager.java:578)
android.support.v7.widget.RecyclerView.dispatchLayoutStep2 (RecyclerView.java:3315)
android.support.v7.widget.RecyclerView.onMeasure (RecyclerView.java:2843)
android.view.View.measure (View.java:18788)
android.view.ViewGroup.measureChildWithMargins (ViewGroup.java:5951)
android.widget.LinearLayout.measureChildBeforeLayout (LinearLayout.java:1465)
android.widget.LinearLayout.measureVertical (LinearLayout.java:748)
android.widget.LinearLayout.onMeasure (LinearLayout.java:630)
android.view.View.measure (View.java:18788)
android.widget.ScrollView.measureChildWithMargins (ScrollView.java:1283)
android.widget.FrameLayout.onMeasure (FrameLayout.java:194)
android.widget.ScrollView.onMeasure (ScrollView.java:340)
android.view.View.measure (View.java:18788)
android.view.ViewGroup.measureChildWithMargins (ViewGroup.java:5951)
android.widget.LinearLayout.measureChildBeforeLayout (LinearLayout.java:1465)
android.widget.LinearLayout.measureVertical (LinearLayout.java:748)
android.widget.LinearLayout.onMeasure (LinearLayout.java:630)
android.view.View.measure (View.java:18788)
android.widget.RelativeLayout.measureChildHorizontal (RelativeLayout.java:715)
android.widget.RelativeLayout.onMeasure (RelativeLayout.java:461)
android.view.View.measure (View.java:18788)
android.view.ViewGroup.measureChildWithMargins (ViewGroup.java:5951)
android.widget.FrameLayout.onMeasure (FrameLayout.java:194)
android.support.v7.widget.ContentFrameLayout.onMeasure (ContentFrameLayout.java:135)
android.view.View.measure (View.java:18788)
android.view.ViewGroup.measureChildWithMargins (ViewGroup.java:5951)
android.widget.LinearLayout.measureChildBeforeLayout (LinearLayout.java:1465)
android.widget.LinearLayout.measureVertical (LinearLayout.java:748)
android.widget.LinearLayout.onMeasure (LinearLayout.java:630)
android.view.View.measure (View.java:18788)
android.view.ViewGroup.measureChildWithMargins (ViewGroup.java:5951)
android.widget.FrameLayout.onMeasure (FrameLayout.java:194)
android.view.View.measure (View.java:18788)
android.view.ViewGroup.measureChildWithMargins (ViewGroup.java:5951)
android.widget.LinearLayout.measureChildBeforeLayout (LinearLayout.java:1465)
android.widget.LinearLayout.measureVertical (LinearLayout.java:748)
android.widget.LinearLayout.onMeasure (LinearLayout.java:630)
android.view.View.measure (View.java:18788)
android.view.ViewGroup.measureChildWithMargins (ViewGroup.java:5951)
android.widget.FrameLayout.onMeasure (FrameLayout.java:194)
com.android.internal.policy.PhoneWindow$DecorView.onMeasure (PhoneWindow.java:2643)
android.view.View.measure (View.java:18788)
android.view.ViewRootImpl.performMeasure (ViewRootImpl.java:2100)
android.view.ViewRootImpl.measureHierarchy (ViewRootImpl.java:1216)
android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:1452)
android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1107)
android.view.ViewRootImpl$TraversalRunnable.run (ViewRootImpl.java:6013)
android.view.Choreographer$CallbackRecord.run (Choreographer.java:858)
android.view.Choreographer.doCallbacks (Choreographer.java:670)
android.view.Choreographer.doFrame (Choreographer.java:606)
android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:844)
android.os.Handler.handleCallback (Handler.java:739)
android.os.Handler.dispatchMessage (Handler.java:95) 

Мой ViewHolder в отдельном файле CommentHolder.java с общедоступным:

public class CommentHolder extends RecyclerView.ViewHolder
    implements View.OnClickListener {
TextView tvComment = null;
TextView tvUser = null;
TextView tvDate = null;
String emailComment = "";
String commentKey, catalogKey;

FirebaseAuth auth;
FirebaseDatabase database;
CommentHolder(View row) {
    super(row);
    auth=FirebaseAuth.getInstance();
    database=FirebaseDatabase.getInstance();

    tvComment = (TextView) row.findViewById(R.id.comment);
    tvUser = (TextView) row.findViewById(R.id.user);
    tvDate = (TextView) row.findViewById(R.id.datecomment);

    row.setOnClickListener(this);
}

@Override
public void onClick(final View v) {

    if (auth.getCurrentUser() == null || auth.getCurrentUser().getEmail() == null) {

        Toast.makeText(v.getContext(), "Harap login terlebih dahulu", Toast.LENGTH_LONG).show();
        return;
    }
    if (!auth.getCurrentUser().getEmail().equalsIgnoreCase(emailComment)) {
        Toast.makeText(v.getContext(), "Anda hanya dapat mengedit komentar yang Anda buat", Toast.LENGTH_LONG).show();
        return;
    }


    final View form = ((Activity) v.getContext()).getLayoutInflater().inflate(R.layout.dialog_comment, null);
    EditText etComment = (EditText) form.findViewById(R.id.editTextComment);
    etComment.setText(tvComment.getText().toString());

    AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());

    builder
            .setTitle("Komentar Anda")
            .setView(form)
            .setPositiveButton("Kirim", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    final EditText etComment = (EditText) form.findViewById(R.id.editTextComment);
                    DatabaseReference commentRef = database.getReference(MyConstants.FB_COMMENT)
                            .child(catalogKey).child(commentKey);
                    Comment comment = new Comment(auth.getCurrentUser().getUid()
                            , auth.getCurrentUser().getEmail(), etComment.getText().toString());
                    commentRef.setValue(comment);

                }
            })
            .setNegativeButton("Batal", null)
            .setNeutralButton("Hapus", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    DatabaseReference commentRef = database.getReference(MyConstants.FB_COMMENT)
                            .child(catalogKey).child(commentKey);
                    commentRef.removeValue();
                }
            })
            .show();


}

void bindModel(String catalogKey, String commentKey, String comment, String emailComment, String dateComment) {
    tvComment.setText(comment);
    String temp = emailComment.replaceAll("(?<=.).(?=[^@]*?.@)", "*");
    tvUser.setText(temp);
    tvDate.setText(dateComment);
    this.emailComment = emailComment;
    this.commentKey = commentKey;
    this.catalogKey = catalogKey;
}

}

Код FirebaseRecyclerAdapter:

mAdapter = new FirebaseRecyclerAdapter<Comment, CommentHolder>(Comment.class, R.layout.play_row
            , CommentHolder.class, commentRef) {
        @Override
        public void populateViewHolder(CommentHolder commentHolder, Comment comment, int position) {

            Date date = new Date((long) comment.getLastUpdate().get("date"));
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
            String strDate = simpleDateFormat.format(date);
            commentHolder.bindModel(catalogKey, getRef(position).getKey(), comment.getComment(), comment.getEmail(), strDate);

        }

    };

Мой комментарий.java:

public class Comment {
String uid;
String email;
String comment;
HashMap<String, Object> lastUpdate;

public Comment() {
}

public Comment(String uid, String email, String comment) {
    this.uid=uid;
    this.email = email;
    this.comment = comment;
    HashMap<String, Object> lastUpdateObj = new HashMap<>();
    lastUpdateObj.put("date", ServerValue.TIMESTAMP);
    this.lastUpdate = lastUpdateObj;


}

public String getUid() {
    return uid;
}

public String getEmail() {
    return email;
}

public String getComment() {
    return comment;
}

public HashMap<String, Object> getLastUpdate() {
    return lastUpdate;
}
}

person Plugie    schedule 20.09.2016    source источник
comment
Пожалуйста, отредактируйте свой вопрос, чтобы предоставить минимальный воспроизводимый пример, включая трассировку стека Java, связанную с вашим сбоем, и вашу реализацию FirebaseRecyclerAdapter.   -  person CommonsWare    schedule 22.09.2016
comment
@CommonsWare да, спасибо. Просто добавил трассировку стека Java и мой код   -  person Plugie    schedule 22.09.2016
comment
Просто предположение: попробуйте создать конструктор CommentHolder public и посмотрите, что получится.   -  person CommonsWare    schedule 22.09.2016
comment
@CommonsWare ты мой герой!!!! Проблема решена после того, как я напрягался в течение 4 дней   -  person Plugie    schedule 22.09.2016
comment
Я не уверен, почему это работает, поэтому я не буду публиковать ответ здесь. Если минификация отключена, я не вижу, как видимость метода изменит поведение между отладочной и выпускной сборками. Но я рад, что это работает для вас.   -  person CommonsWare    schedule 22.09.2016
comment
Большое спасибо @CommonsWare, я опубликую ваш комментарий в качестве ответа. Если у кого-то еще такая же проблема со мной, найду быстрый ответ   -  person Plugie    schedule 22.09.2016


Ответы (1)


Как предполагает @CommonsWare. Проблема решается добавлением public в конструктор CommentHolder.

public CommentHolder(View row) {
super(row);
auth=FirebaseAuth.getInstance();
database=FirebaseDatabase.getInstance();

tvComment = (TextView) row.findViewById(R.id.comment);
tvUser = (TextView) row.findViewById(R.id.user);
tvDate = (TextView) row.findViewById(R.id.datecomment);

row.setOnClickListener(this);
}
person Plugie    schedule 22.09.2016
comment
@souttab Пожалуйста, отредактируйте свой комментарий, чтобы предоставить минимальный, полный и проверяемый пример :) - person Plugie; 03.12.2016
comment
все еще сталкиваюсь с проблемой - person Nouman Ch; 28.09.2017
comment
Я столкнулся с той же проблемой, хотя мой конструктор общедоступен. Однако у меня minifyEnabled true, так как я хочу использовать ProGuard. - person Sandra; 04.02.2018