My app on Android studio crash after I create the first data

30 views Asked by At

If I dont have any type (the object) in my db then the app run normally, but after I add the fist thing to the db it crash right away and if i run it againt it still crash.

I don't know what to do. Is it because it cant read data or is it because im not create anything in the beginning? 35 : lstType = TypeDataQuery.getAll(this); If I delete this line thing run as normal

package com.example.myspinner;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import java.util.ArrayList;

public class TypeActivity extends AppCompatActivity implements TypeAdapter.TypeCallBack {
    TextView tvHeaderC;
    RecyclerView rcListCode;
    ArrayList<Type> lstType;
    TypeAdapter typeAdapter;
    FloatingActionButton fbTypeAdd;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_type);
        tvHeaderC = findViewById(R.id.tvTypeHeader);
        rcListCode = findViewById(R.id.rvTypeList);
        fbTypeAdd = findViewById(R.id.fbTypeAdd);
        fbTypeAdd.setOnClickListener(view -> addTypeDialog());

        lstType = new ArrayList<>();
        lstType = TypeDataQuery.getAll(this);
        typeAdapter = new TypeAdapter(lstType);
        typeAdapter.setTypeCallBack((TypeAdapter.TypeCallBack) this);

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        rcListCode.setAdapter(typeAdapter);
        rcListCode.setLayoutManager(linearLayoutManager);
    }
    void addTypeDialog()
    {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(TypeActivity.this);
        alertDialog.setTitle("Thêm mới");
        LayoutInflater inflater = this.getLayoutInflater();
        View dialogView = inflater.inflate(R.layout.dialog_add_type, null);
        alertDialog.setView(dialogView);
        EditText edTypeName = dialogView.findViewById(R.id.edTypeName);
        alertDialog.setPositiveButton("Đồng ý", ((dialog, which) ->
        {
            String name = edTypeName.getText().toString();
            if (name.isEmpty())
                Toast.makeText(TypeActivity.this, "Nhập dữ liệu không hợp lệ", Toast.LENGTH_LONG).show();
            else {
                Type type = new Type(0, name);
                long id = TypeDataQuery.insert(TypeActivity.this, type);
                if (id > 0) {
                    Toast.makeText(TypeActivity.this, "Thêm loại thành công.", Toast.LENGTH_LONG).show();
                    resetData();
                    dialog.dismiss();
                }
            }
        }
        ));
        alertDialog.setNegativeButton("Hủy", ((dialog, which) ->
        {
            dialog.dismiss();
        }
        ));
        alertDialog.create();
        alertDialog.show();
    }
    void resetData() {
        lstType.clear();
        lstType.addAll(TypeDataQuery.getAll(TypeActivity.this));
        typeAdapter.notifyDataSetChanged();
    }
    void updateUserDialog(Type type) {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(TypeActivity.this);
        alertDialog.setTitle("Cập nhật");
        LayoutInflater inflater = this.getLayoutInflater();
        View dialogView = inflater.inflate(R.layout.dialog_add_type, null);
        alertDialog.setView(dialogView);
        EditText edName = (EditText) dialogView.findViewById(R.id.edTypeName);

        edName.setText(type.getName());
        alertDialog.setPositiveButton("Đồng ý", (dialog, which) -> {
            type.setName(edName.getText().toString());
            if (type.name.isEmpty())
                Toast.makeText(TypeActivity.this, "Nhập dữ liệu không hợp lệ", Toast.LENGTH_LONG).show();
            else {
                int id = TypeDataQuery.update(TypeActivity.this, type);
                if (id > 0) {
                    Toast.makeText(TypeActivity.this, "Cập nhật người dùng thành công.", Toast.LENGTH_LONG).show();
                    resetData();
                    dialog.dismiss();
                }
            }
        });
        alertDialog.setNegativeButton("Hủy", (dialog, which) -> {
            dialog.dismiss();
        });
        alertDialog.create();
        alertDialog.show();
    }

    @Override
    public void onItemDeleteClicked(Type type, int position) {
        boolean rs = TypeDataQuery.delete(TypeActivity.this, type.id);
        if (rs) {
            Toast.makeText(this, "Xoá thành công", Toast.LENGTH_LONG).show();
            resetData();
        } else {
            Toast.makeText(this, "Xoá thất bại", Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onItemEditClicked(Type type, int position) {
        updateUserDialog(type);
    }
}
package com.example.myspinner;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class UserDBHelper extends SQLiteOpenHelper {
    private static final String DATABASE_NAME = utils.DATABASE_NAME;
    private static final int DATABASE_VERSION = 4;
    public UserDBHelper(Context context)
    {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String CREATE_USER_TABLE = "CREATE TABLE " + utils.TABLE_USER + " ("
                + utils.COLUMN_USER_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                + utils.COLUMN_USER_NAME + " TEXT, "
                + utils.COLUMN_USER_AVATAR + " TEXT" + ");";

        String CREATE_TYPE_TABLE = "CREATE TABLE " + utils.TABLE_TYPE + " ("
                + utils.COLUMN_TYPE_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                + utils.COLUMN_TYPE_NAME + " TEXT" + ");" ;
        db.execSQL(CREATE_USER_TABLE);
        db.execSQL(CREATE_TYPE_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + utils.TABLE_USER);
        db.execSQL("DROP TABLE IF EXISTS " + utils.TABLE_TYPE);
        onCreate(db);
    }
}

package com.example.myspinner;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import java.util.ArrayList;

public class TypeDataQuery {
    public static long insert(Context context, Type type)
    {
        UserDBHelper userDBHelper = new UserDBHelper(context);
        SQLiteDatabase sqLiteDatabase = userDBHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(utils.COLUMN_TYPE_NAME, type.name);
        long rs = sqLiteDatabase.insert(utils.TABLE_TYPE, null, values);
        return (rs);
    }
    public static ArrayList<Type> getAll(Context context)
    {
        ArrayList<Type> lstUser = new ArrayList<>();
        UserDBHelper userDBHelper = new UserDBHelper(context);
        SQLiteDatabase db = userDBHelper.getReadableDatabase();
        Cursor cs = db.rawQuery("Select * from " + utils.TABLE_TYPE, null);
        cs.moveToFirst();
        while (!cs.isAfterLast())
        {
            int id = cs.getInt(0);
            String name = cs.getString(1);
            Type type = new Type(id, name);
            lstUser.add(type);
            cs.moveToNext();
        }
        cs.close();
        db.close();
        return lstUser;
    }
    public static boolean delete(Context context, int id)
    {
        UserDBHelper userDBHelper = new UserDBHelper(context);
        SQLiteDatabase sqLiteDatabase = userDBHelper.getWritableDatabase();
        int rs = sqLiteDatabase.delete(utils.TABLE_TYPE, utils.COLUMN_TYPE_ID+"=?", new String[]{String.valueOf(id)});
        return (rs > 0);
    }
    public static int update(Context context, Type type)
    {
        UserDBHelper userDBHelper = new UserDBHelper(context);
        SQLiteDatabase sqLiteDatabase = userDBHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(utils.COLUMN_TYPE_NAME, type.name);
        int rs = sqLiteDatabase.update(utils.TABLE_TYPE, values, utils.COLUMN_TYPE_ID+"=?", new String[] {String.valueOf(type.id)} );
        return (rs);
    }
}

package com.example.myspinner;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
public class TypeAdapter extends RecyclerView.Adapter<TypeAdapter.TypeViewHolder> {
    ArrayList<Type> lstType;
    Context context;
    TypeCallBack typeCallBack;
    public TypeAdapter(ArrayList<Type> lstType) {
        this.lstType = lstType;
    }
    public void setTypeCallBack(TypeCallBack typeCallBack)
    {
        this.typeCallBack = typeCallBack;
    }

    @NonNull
    @Override
    public TypeViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        context = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);
        View typeView = inflater.inflate(R.layout.layoutitem, parent, false);
        return new TypeViewHolder(typeView);
    }

    @Override
    public void onBindViewHolder(@NonNull TypeViewHolder holder, int position) {
        Type item = lstType.get(position);
        if(item != null)
        {
            holder.tvName.setText(item.getName());
            holder.ivEdit.setOnClickListener(view -> typeCallBack.onItemEditClicked(item, position));
            holder.ivDelete.setOnClickListener(view -> typeCallBack.onItemDeleteClicked(item, position));
        }

    }

    @Override
    public int getItemCount() {
        return lstType.size();
    }
    static class TypeViewHolder extends RecyclerView.ViewHolder
    {
        TextView tvName;
        ImageView ivEdit;
        ImageView ivDelete;
        public TypeViewHolder(@NonNull View itemView) {
            super(itemView);
            tvName = itemView.findViewById(R.id.tvTypeName);
            ivEdit = itemView.findViewById(R.id.ivTypeEdit);
            ivDelete = itemView.findViewById(R.id.ivTypeDelete);
        }
    }
    public interface TypeCallBack
    {
        void onItemDeleteClicked(Type type, int position);
        void onItemEditClicked(Type type, int position);
    }
}

package com.example.myspinner;

public class Type {
    int id;
    String name;

    public Type(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

enter image description here

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference at com.example.myspinner.TypeAdapter.onBindViewHolder(TypeAdapter.java:40) at com.example.myspinner.TypeAdapter.onBindViewHolder(TypeAdapter.java:14) Maybe this is the reason, but I dont know how to fix it.

2

There are 2 answers

2
MikeT On

IF there is no data to be extracted then the result of moveToFirst will be false (the move to the first row could not be accomplished). If without checking the result you then try to extract data then an exception (crash) will occur.

You SHOULD check to see if the moveToFirst was successful.

Simpler and more concise to use:-

    Cursor cs = db.rawQuery("Select * from " + utils.TABLE_TYPE, null);
    //cs.moveToFirst();
    while (cs.moveToNext)
    {
        int id = cs.getInt(0);
        String name = cs.getString(1);
        Type type = new Type(id, name);
        lstUser.add(type);
    }
  • Note that the line cs.moveToFirst has been commented out (otherwise 1 row would be skipped). Obviously the line could be deleted (left in to illustrate).
  • moveToNext will effectively move to the first row from the position before the first row or return false if the move cannot be made.
0
Random guy On

Problem solved. I just use the wrong layout to display the item so it crash whenever there are data in the database. Thank you for spending your time for me Mike.