при работе с RecyclerView возникает ошибка java.lang.RuntimeException: Unable to start activity ComponentInfo

317
14 ноября 2021, 04:00

Пишу что-то вроде текстового редактора, текст в котором добавляется в элементе:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
    <Button
        android:id="@+id/buttonSave"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/save"
        android:layout_weight="0"
        android:textSize="25sp"
        android:layout_marginTop="20dp"
        android:layout_marginLeft="20dp"
        />
    <Button
        android:id="@+id/btnRead"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="0"
        android:layout_toRightOf="@id/buttonSave"
        android:text="@string/read"
        android:textSize="25sp"
        android:layout_marginTop="20dp"
        android:layout_marginLeft="20dp"
        />
    <Button
        android:id="@+id/btnDell"
        android:layout_width="wrap_content"
        android:layout_below="@id/btnRead"
        android:text="удалить"
        android:textSize="25sp"
        android:layout_marginTop="20dp"
        android:layout_marginLeft="20dp"
        android:layout_height="wrap_content"
        />

    <EditText
        android:id="@+id/editText2"
        android:layout_below="@id/btnDell"
        android:layout_marginTop="16dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Введите название записи"
        android:inputType="textMultiLine"
        android:gravity="top"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"/>
    <EditText
        android:id="@+id/editText1"
        android:layout_below="@id/editText2"
        android:layout_marginTop="16dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:hint="Введите запись"
        android:inputType="textMultiLine"
        android:gravity="top"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"/>
    </RelativeLayout>

Заносится в базу данных sqlite:

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBHelper  extends SQLiteOpenHelper{
    public static final int DATABASE_VERSION = 4;
    public static final String DATABASE_NAME = "contactDb";
    public static final String TABLE_TEXT = "text";
    public static final String KEY_ID = "_id";
    public static final String KEY_NAME = "name";
    public static final String KEY_TEXT = "text";
    public DBHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table " + TABLE_TEXT + "(" + KEY_ID
                + " integer primary key," + KEY_NAME + " text," + KEY_TEXT + " text" + ")");
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("drop table if exists " + TABLE_TEXT);
        onCreate(db);
    }
}

После имена текстовых элементов из базы данных передаются в элемент RecyclerView:

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_num"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </androidx.recyclerview.widget.RecyclerView>
</FrameLayout>

Активность списка RecyclerView:

import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class postsList extends Activity {
    private RecyclerView recyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager layoutManager;
    private DBHelper mDataBaseHelper;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_posts_list);
        recyclerView = (RecyclerView) findViewById(R.id.rv_num);
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        SQLiteDatabase db = mDataBaseHelper.getReadableDatabase();
        String sql = "select name, text from text";
        Cursor c = db.rawQuery(sql, new String[]{});
        List<TextRow> myDataset = new ArrayList<>();
        if (c != null) {
            if (c.moveToFirst()) {
                do {
                    int idId= c.getColumnIndex("_id");
                    int idName= c.getColumnIndex("name");
                    int idText= c.getColumnIndex("text");
                    myDataset.add(new TextRow(c.getInt(idId),c.getString(idName),c.getString(idText)));
                } while (c.moveToNext());
            }
            c.close();
        }
        mAdapter = new MyAdapter(myDataset);
        recyclerView.setAdapter(mAdapter);
        if(this.mDataBaseHelper == null){
            this.mDataBaseHelper = new DBHelper(this);
        }
        db = mDataBaseHelper.getWritableDatabase();
        db.execSQL("insert into text (_id,name,text)values(1,'MyFirstName','MyFirstText')");
    }
}

Адаптер:

import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    private List<TextRow> mDataset;
    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    public static class MyViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public TextView textView;
        public MyViewHolder(TextView v) {
            super(v);
            textView = v;
        }
    }
    public MyAdapter(List<TextRow> myDataset) { //откуда брать массив???
        mDataset = myDataset;
    }
    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
                                                     int viewType) {
        // create a new view
        TextView v = (TextView) LayoutInflater.from(parent.getContext())
                .inflate(R.layout.activity_new_entry, parent, false);
        MyViewHolder vh = new MyViewHolder(v);
        return vh;
    }
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element
        holder.textView.setText(mDataset.get(position).name);
    }
    @Override
    public int getItemCount() {
        return mDataset.size();
    }  
}

Когда запускаю приложение и нажимаю на активность списка RecyclerView, приложение вылетает и появляется ошибка:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.posts, PID: 2528
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.posts/com.example.posts.postsList}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase com.example.posts.DBHelper.getReadableDatabase()' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase com.example.posts.DBHelper.getReadableDatabase()' on a null object reference
        at com.example.posts.postsList.onCreate(postsList.java:32)
        at android.app.Activity.performCreate(Activity.java:7009)
        at android.app.Activity.performCreate(Activity.java:7000)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) 
        at android.app.ActivityThread.-wrap11(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6494) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 

Также красным выделяется xml файл encodings.xml, код этого файла:

<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="Encoding">
    <file url="file://$USER_HOME$/OneDrive/Документы/AndroidStudio/DeviceExplorer/emulator-5554/data/data/com.example.posts/databases/contactDb" charset="windows-1251" />
    <file url="PROJECT" charset="UTF-8" />
  </component>
</project>

Может быть дело в нём? Подскажите, пожалуйста, что мне делать в этой ситуации

Answer 1

У Тебя

SQLiteDatabase db = mDataBaseHelper.getReadableDatabase();

здесь еще не инициализирован mDataBaseHelper. Сперва нужно сделать это

if(this.mDataBaseHelper == null){
        this.mDataBaseHelper = new DBHelper(this);
}

Сделайте в DBHelper лучше id как AUTOINCREMENT

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("create table " + TABLE_TEXT + "(" + KEY_ID
            + " integer primary key AUTOINCREMENT," + KEY_NAME + " text," + KEY_TEXT + " text" + ")");
}

а в postsList activity сперва заполните таблицу

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.test1);
    recyclerView = (RecyclerView) findViewById(R.id.rv_num);
    layoutManager = new LinearLayoutManager(this);
    recyclerView.setLayoutManager(layoutManager);
    if(this.mDataBaseHelper == null){
        this.mDataBaseHelper = new DBHelper(this);
    }
    SQLiteDatabase db  = mDataBaseHelper.getWritableDatabase();
    db.execSQL("insert into text (name,text)values('MyFirstName','MyFirstText')");
    db.execSQL("insert into text (name,text)values('MyFirstName2','MyFirstText2')");
    db.execSQL("insert into text (name,text)values('MyFirstName3','MyFirstText3')");
    db.execSQL("insert into text (name,text)values('MyFirstName4','MyFirstText4')");
     db = mDataBaseHelper.getReadableDatabase();
    String sql = "select name, text from text";
    Cursor c = db.rawQuery(sql, new String[]{});
    List<String> myDataset = new ArrayList<>();
.....
}
READ ALSO
Как нарисовать векторное изображение canvas

Как нарисовать векторное изображение canvas

Как используя canvas нарисовать VectorDrawableОбычный Drawable у меня получается нарисовать конвертацией в Bitmap, но как нарисовать VectorDrawable, возможно ли это?

173
Как выстроить структуру классов?

Как выстроить структуру классов?

Дорый день! У меня есть тестовое заданиеКейс сбора данных:

334
return пустой массив

return пустой массив

Как вернуть пустой массив в методе?

133
Ограничение записи массива в массив

Ограничение записи массива в массив

Пришлось немного подхимичить код чтобы при загрузке на сайт универа не одинаков былВ общем где тут дописать чтобы при двух массивах с одним...

167