由于尝试在空对象引用上调用虚拟方法“ ”,应用程序崩溃

Posted

技术标签:

【中文标题】由于尝试在空对象引用上调用虚拟方法“ ”,应用程序崩溃【英文标题】:App crashes because of attempt to invoke virtual method ' ' on a null object reference 【发布时间】:2021-08-02 17:27:00 【问题描述】:

我正在尝试在单击 recyclerview 中的图像时显示自定义对话框。但是,虽然编译时代码中没有明显的错误,但当我单击菜单项进入页面时,我的应用程序一直在崩溃。 logcat中的错误说:

java.lang.NullPointerException: Attempt to invoke virtual method 'void de.hdodenhof.circleimageview.CircleImageView.setImageResource(int)' on a null object reference
        at com.example.android.myndapplication.adapter.UserAdapter.onBindViewHolder(UserAdapter.java:61)
        at com.example.android.myndapplication.adapter.UserAdapter.onBindViewHolder(UserAdapter.java:25)
        at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7254)
        at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7337)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6194)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6460)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6300)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6296)
        at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2330)
        at androidx.recyclerview.widget.GridLayoutManager.layoutChunk(GridLayoutManager.java:572)
        at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1591)
        at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:668)
        at androidx.recyclerview.widget.GridLayoutManager.onLayoutChildren(GridLayoutManager.java:170)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4309)
        at androidx.recyclerview.widget.RecyclerView.onMeasure(RecyclerView.java:3686)

下面我插入了我目前关于此事的代码:

** UserAdapter.java**

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.android.myndapplication.R;
import com.example.android.myndapplication.model.User;

import org.w3c.dom.Text;

import java.util.List;

import de.hdodenhof.circleimageview.CircleImageView;

public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder> 

    private Context mContext;
    private List<User> userList;
    Dialog myDialog;




    public UserAdapter(Context mContext, List<User> userList) 
        this.mContext = mContext;
        this.userList = userList;

    

    @NonNull
    @Override
    public UserAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_list_item, parent, false);
        final ViewHolder ViewHolder = new ViewHolder(view);

        // Dialog ini
        myDialog = new Dialog(mContext);
        myDialog.setContentView(R.layout.dialog_profile);
        CircleImageView iv_profile = (CircleImageView) myDialog.findViewById(R.id.dialog_profile_image);
        TextView tv_username = (TextView) myDialog.findViewById(R.id.dialog_profile_username);
        TextView tv_date = (TextView) myDialog.findViewById(R.id.dialog_profile_date);
        ImageView iv_content = (ImageView) myDialog.findViewById(R.id.dialog_content_image);

        return new ViewHolder(view);
    

    @Override
    public void onBindViewHolder(@NonNull UserAdapter.ViewHolder holder, final int position) 

        final User user = userList.get(position);
        holder.iv_profile.setImageResource(user.getProfileImage());
        holder.userName.setText(user.getUserName());
        holder.userDate.setText(user.getUserDate());
        holder.image_content.setImageResource(user.getImage());
        holder.item.setOnClickListener(new View.OnClickListener() 

            @Override
            public void onClick(View view) 
                Toast.makeText(mContext, "Test Click"+userList.get(position), Toast.LENGTH_SHORT).show();
                myDialog.show();
            
        );
    

    @Override
    public int getItemCount() 
        return userList.size();
    

    public class ViewHolder extends RecyclerView.ViewHolder 

        private CardView item;
        private CircleImageView iv_profile;
        private TextView userName;
        private TextView userDate;
        private ImageView image_content;
        private ImageView imageView;
        private TextView textView;


        public ViewHolder(View itemView) 
            super(itemView);

            imageView = itemView.findViewById(R.id.img_bookmarks);
            textView = itemView.findViewById(R.id.title_bookmarks);
            item = (CardView) itemView.findViewById(R.id.profile_item);
            iv_profile = (CircleImageView) itemView.findViewById(R.id.dialog_profile_image);
            userName = (TextView) itemView.findViewById(R.id.dialog_profile_username);
            userDate = (TextView) itemView.findViewById(R.id.dialog_profile_date);
            image_content = (ImageView) itemView.findViewById(R.id.dialog_content_image);

            //test
            //itemView.setOnClickListener((View.OnClickListener) this);
        
    


User.java

public class User 

    private int image;
    private String Title;
    private String UserName;
    private int profileImage;
    private String userDate;


    public String getUserDate() 
        return userDate;
    

    public void setUserDate(String userDate) 
        this.userDate = userDate;
    

    public User(int image, String Title, String userName, int profileImage, String userDate) 
        this.image = image;
        this.Title = Title;
        this.UserName = userName;
        this.profileImage = profileImage;
        this.userDate = userDate;
    

    public String getUserName() 
        return UserName;
    

    public int getProfileImage() 
        return profileImage;
    

    public void setProfileImage(int profileImage) 
        this.profileImage = profileImage;
    

    public int getImage() 
        return image;
    

    public void setImage(int image) 
        this.image = image;
    

    public String getTitle() 
        return Title;
    

    public void setUserName(String Title) 
        this.Title = Title;
    

dialog_profile.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_
    android:layout_>


    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/dialog_profile_image"
        android:layout_
        android:layout_
        android:layout_marginStart="10dp"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"
        android:src="@mipmap/ic_launcher_round"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/dialog_profile_username"
        android:layout_
        android:layout_
        android:layout_marginStart="10dp"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"
        android:text="@string/username"
        android:textSize="10sp"
        app:layout_constraintStart_toEndOf="@+id/dialog_profile_image"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/dialog_profile_date"
        android:layout_
        android:layout_
        android:layout_marginStart="10dp"
        android:layout_marginLeft="10dp"
        android:text="date"
        android:textSize="8sp"
        app:layout_constraintStart_toEndOf="@+id/dialog_profile_image"
        app:layout_constraintTop_toBottomOf="@+id/dialog_profile_username" />


    <ImageView
        android:id="@+id/dialog_content_image"
        android:layout_
        android:layout_
        android:layout_marginTop="70dp"
        android:scaleType="fitXY"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

我检查了我的 id,并试图确保我有 setContentView,因为我已经看到与我的问题类似的问题。但是,似乎没有任何效果,我无法真正发现错误。希望能帮到你!

【问题讨论】:

【参考方案1】:

您没有收到编译时错误的原因是您在 dialog_profile.xml 布局中的这些 ID 有效,但回收站项目布局不同,即 recycler_list_item 请参阅您的 onCreateViewHolder

这就是CircleImageView 上出现运行时 NullPointerException 的原因,因为这不是您的 recycler_list_item 的一部分,它当前在创建适配器时被夸大了。

注意:始终确保您在 viewholder 中使用的视图在布局适配器中正在膨胀,因为如果您做错了,但在运行时,您不会收到编译时错误,它会崩溃。

【讨论】:

【参考方案2】:

我不确定,但是,在“OnBindViewHolder”中,您可以尝试从视图持有者的 itemView 访问“iv_profile”吗?

我的意思是这样的:

holder.itemView.iv_profile.setImageResource(user.getProfileImage());

而不是这个:

holder.iv_profile.setImageResource(user.getProfileImage());

我的假设是您的引用在视图中,而不是绑定到持有者本身。

【讨论】:

我有一个疑问。您可以尝试在“OnCreateViewHolder”块之外声明“CircleImageView iv_profile”吗?

以上是关于由于尝试在空对象引用上调用虚拟方法“ ”,应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Android错误尝试在空对象引用上调用虚拟方法[重复]

在使用 Recycler View 时尝试在空对象引用上调用虚拟方法

NullPointerException 错误尝试在空对象引用上调用虚拟方法错误

NullPointerException:尝试在空对象引用上调用虚拟方法 findViewById(int)'

尝试在空对象引用上调用虚拟方法 com.google.firebase.iid.FirebaseInstanceId.getInstanceId()'

AsyncTask +数据库尝试在空对象引用上调用虚拟方法[重复]