Home > OS >  RecyclerView: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.cont
RecyclerView: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.cont

Time:05-29

First of all, I am completefy noob to android development and I am making this project for my college where I display items in a Recycler view, each Item has a delete button and it updates the product quantity, reloads the recycer view.

The recycler view is getting displayed the problem is with refreshing it when a item is deleted.

Adapter Class

public class ProductAdaptar extends RecyclerView.Adapter<ProductAdaptar.ProductAdaptarVH> {

private List<UserLoginResp> productListItems;
private Context context;

public ProductAdaptar() {
}

public void setData(List<UserLoginResp> productListItems) {
    this.productListItems = productListItems;
    notifyDataSetChanged();
}

@NonNull
@Override
public ProductAdaptarVH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    context = parent.getContext();
    return new ProductAdaptar.ProductAdaptarVH(LayoutInflater.
            from(context).inflate(R.layout.row_products,parent,false));
}

@Override
public void onBindViewHolder(@NonNull ProductAdaptarVH holder, int position) {
    UserLoginResp userLoginResp = productListItems.get(position);
    String pName = userLoginResp.getProductName();
    Log.e("Pname","" pName);
    String pQuan = userLoginResp.getQuantity();
    Log.e("Pquan","" pQuan);
    String pPrice = userLoginResp.getProductPrice();
    Log.e("Pprice","" pPrice);
    String pBarcode = userLoginResp.getProductID();
    Log.e("PBarcode","" pBarcode);
    String userID = userLoginResp.getUserID();
    Log.e("userid","" userID);
    holder.pName.setText(pName);
    holder.pQuan.setText(pQuan);
    holder.pPrice.setText(pPrice);
    holder.delProdcut.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            delProduct(userID,pBarcode);
        }
    });

}

public void delProduct(String userID, String pBarcode){
    Call<String> res = ApiClient.getUserPageService().deleteProduct(pBarcode,userID);
    res.enqueue(new Callback<String>() {
        @Override
        public void onResponse(Call<String> call, Response<String> response) {
            if(response.isSuccessful()){
                new UserPage().getAllProducts(userID);
            }
        }
        @Override
        public void onFailure(Call<String> call, Throwable t) {
                Log.e("deletefailed","" t);
                new UserPage().getAllProducts(userID);
        }
    });
}

@Override
public int getItemCount() {
        return productListItems.size();
}

public static class ProductAdaptarVH extends RecyclerView.ViewHolder {

    TextView pName;
    TextView pQuan;
    TextView pPrice;
    Button delProdcut;

    public ProductAdaptarVH(@NonNull View itemView) {
        super(itemView);
         pName=itemView.findViewById(R.id.pName);
         pQuan=itemView.findViewById(R.id.pQuantity);
         pPrice=itemView.findViewById(R.id.pPrice);
         delProdcut=itemView.findViewById(R.id.delProduct);
    }
}
}

User Page Activity

public class UserPage extends AppCompatActivity implements ProductAdaptar.deleteProduct {
    Toolbar toolbar;
    RecyclerView recyclerView;
    String rfidNo;
    ProductAdaptar productAdaptar;
    Call<List<UserLoginResp>> productList;
    List<UserLoginResp> productListsItems = new ArrayList<>();
    

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_user_page);
        toolbar=findViewById(R.id.toolbar);
        recyclerView=findViewById(R.id.recyclerview);

        LinearLayoutManager manager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(manager);
        recyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));
        productAdaptar = new ProductAdaptar(this::delProduct);

        Intent intent =getIntent();
        if(intent.getExtras()!=null){
            rfidNo= intent.getStringExtra("rfid");
        }

        getAllProducts(rfidNo);
    }
        public void getAllProducts(String rfidno){
            productAdaptar = new ProductAdaptar();
            productList= ApiClient.getUserPageService().getCartItems(rfidno);
            productList.enqueue(new Callback<List<UserLoginResp>>() {
                @Override
                public void onResponse(Call<List<UserLoginResp>> call, Response<List<UserLoginResp>> response) {
                    if (response.isSuccessful()) {
                        productListsItems = response.body();
                        productAdaptar.setData(productListsItems);
                        RecyclerView recyclerView = findViewById(R.id.recyclerview);
                        recyclerView.setAdapter(productAdaptar);
                    }
                }
                @Override
                public void onFailure(Call<List<UserLoginResp>> call, Throwable t) {
                    Log.e("listfailed",t.getLocalizedMessage());
                }
            });
    }



@Override
public void delProduct(UserLoginResp userLoginResp) {
        Log.e("delted prodcut", userLoginResp.toString());
}
}

So, the api is working perfectly, the DB is getting updated the problem is that the Recycler View is failing to get refreshed, since I am calling the delProduct() function which in turn calls the getAllProducts() from Userpage Activity its failing to refresh it. The recycler view is getting displayed the problem is with refreshing it when a item is deleted.

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.shopeasy, PID: 27509
    java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
        at android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:159)
        at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:157)
        at android.content.Context.obtainStyledAttributes(Context.java:675)
        at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:842)
        at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:809)
        at androidx.appcompat.app.AppCompatDelegateImpl.findViewById(AppCompatDelegateImpl.java:633)
        at androidx.appcompat.app.AppCompatActivity.findViewById(AppCompatActivity.java:259)
        at com.example.shopeasy.UserPage$1.onResponse(UserPage.java:67)
        at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1.lambda$onResponse$0$retrofit2-DefaultCallAdapterFactory$ExecutorCallbackCall$1(DefaultCallAdapterFactory.java:89)
        at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1$$ExternalSyntheticLambda1.run(Unknown Source:6)
        at android.os.Handler.handleCallback(Handler.java:874)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:198)
        at android.app.ActivityThread.main(ActivityThread.java:6729)
        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:858)

I am complete new to android coding so I can't seem to find a way to fix it.

CodePudding user response:

NEVER create an instance of an activity yourself.

Replace:

private Context context;

public ProductAdaptar() {
}

with:

private UserPage context;

public ProductAdaptar(UserPage activity) {
  context = activity;
}

Then, replace all occurrences of new UserPage() with context, such as:

public void delProduct(String userID, String pBarcode){
    Call<String> res = ApiClient.getUserPageService().deleteProduct(pBarcode,userID);
    res.enqueue(new Callback<String>() {
        @Override
        public void onResponse(Call<String> call, Response<String> response) {
            if(response.isSuccessful()){
                context.getAllProducts(userID);
            }
        }
        @Override
        public void onFailure(Call<String> call, Throwable t) {
                Log.e("deletefailed","" t);
                context.getAllProducts(userID);
        }
    });
}

Also, delete:

context = parent.getContext();

...and replace your call to the ProductAdaptar constructor with one that takes the UserPage activity as a parameter:

productAdaptar = new ProductAdaptar(this);
  • Related