Убедитесь, что курсор инициализирован правильно, прежде чем получить доступ к данным из него. Как его решить? - PullRequest
0 голосов
/ 18 сентября 2018

Я хочу показать мои данные из базы данных SQLite в RecyclerView во фрагменте внутри действия.ошибка iget в строке: contactList.add (m);в Databese helper метод getAllUsers.

это мой logcat:

09-17 18:11:17.487 2101-2101/ir.shirazmetro E/CursorWindow: Failed to read row 0, column 1 from a CursorWindow which has 17 rows, 1 columns.
09-17 18:11:17.487 2101-2101/ir.shirazmetro D/AndroidRuntime: Shutting down VM


    --------- beginning of crash
09-17 18:11:17.487 2101-2101/ir.shirazmetro E/AndroidRuntime: FATAL EXCEPTION: main
    Process: ir.shirazmetro, PID: 2101
    java.lang.IllegalStateException: Couldn't read row 0, col 1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
        at android.database.CursorWindow.nativeGetString(Native Method)
        at android.database.CursorWindow.getString(CursorWindow.java:438)
        at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
        at ir.shirazmetro.DatabaseHelper.getAllUsers(DatabaseHelper.java:89)
        at ir.shirazmetro.views.fragments.toDastgheybFragment.onActivityCreated(toDastgheybFragment.java:58)
        at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:2344)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1446)
        at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1754)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1822)
        at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)
        at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2591)
        at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2378)
        at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2333)
        at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2210)
        at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:649)
        at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:145)
        at android.support.v4.view.ViewPager.populate(ViewPager.java:1239)
        at android.support.v4.view.ViewPager.populate(ViewPager.java:1087)
        at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1617)
        at android.view.View.measure(View.java:17547)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:875)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
        at android.view.View.measure(View.java:17547)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
        at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:141)
        at android.view.View.measure(View.java:17547)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
        at android.view.View.measure(View.java:17547)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
        at android.view.View.measure(View.java:17547)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
        at android.view.View.measure(View.java:17547)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2615)
        at android.view.View.measure(View.java:17547)
        at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2015)
        at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1173)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1379)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5885)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
        at android.view.Choreographer.doCallbacks(Choreographer.java:580)
        at android.view.Choreographer.doFrame(Choreographer.java:550)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Cho

вот мой код:

Activity.java:

public class station extends BaseActivity {
    Toolbar mToolbar;
    private TabLayout tbLayout;
    private ViewPager vPager;
    private ButtonCell backBtn;
    Boolean btnOneOn = false;
    Boolean btnTwoOn = false;
    Boolean btnThreeOn = false;
    Boolean btnfourOn = false;
    ButtonCell Button2;
    ButtonCell Button1;
    ButtonCell Button3;
    ButtonCell Button4;

    private List<DatabaseModel> LineList = new ArrayList<>();
    private RecyclerView recyclerView;
    private DataAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_station);

        mToolbar = findViewById(R.id.tlbr1);
        setSupportActionBar(mToolbar);

        DatabaseHelper helpher;
        helpher = new DatabaseHelper(station.this);
        helpher.insertIntoDB("dastgheyb", "06:10:00", "B");
        helpher.close();
        initView();
        setupWithViewPager();
        tbLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
    }
}

а это DataAdapter.java:

public class DataAdapter extends RecyclerView.Adapter<DataAdapter.MyViewHolder> {
    private List<DatabaseModel> LineList;
    public Context mContext;

    public DataAdapter(Context mContext, List<DatabaseModel> line1List) {
        this.LineList = line1List;
        this.mContext = mContext;
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        TextViewCell Time;

        public MyViewHolder(View view) {
            super(view);
            //initialize textViews and buttons
            Time = view.findViewById(R.id.textView);
        }
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //set item layout using layout inflater
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_to_dastgheyb, parent, false);
        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        final DatabaseModel list = LineList.get(position);
        holder.Time.setText(list.getTime());
    }

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

а это мой фрагмент. java:

public class toDastgheybFragment extends BaseFragment {
    private Activity mActivity = null;
    private View mView;
    private RecyclerFragmentListener mFragmentListener = null;

    // RecyclerViewとAdapter
    private RecyclerView mRecyclerView;
    DataAdapter mAdapter;

    public interface RecyclerFragmentListener {
        void onRecyclerEvent();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mView = inflater.inflate(R.layout.fragment_to_dastgheyb, container, false);
        mRecyclerView = mView.findViewById(R.id.myRecycler);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
        return mView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        Cursor cursor;
        List<DatabaseModel> LineList = new ArrayList<>();
        LineList.clear();
        DatabaseHelper db = new DatabaseHelper(getContext());
        //data from database is returned to m
        final List<DatabaseModel> m = db.getAllUsers();
        Log.w("SIZe", "" + m.size());
        //if m contains data
        if (m.size() > 0) {
            //loop through contents
            for (int i = 0; i < m.size(); i++) {
                Log.w("NAME", m.get(i).getTime());
                //add data to list used in adapter
                LineList.add(m.get(i));
                //notify data change
                mAdapter.notifyDataSetChanged();
            }
        }

        db.close();

        mAdapter = new DataAdapter(mActivity, LineList);
        mRecyclerView.setAdapter(mAdapter);
    }

    public void onRecyclerClicked(View v, int position) {

    }
}

а это мой DataHelper.java:

public class DatabaseHelper extends SQLiteOpenHelper {
    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "MetroDB";//name of the database
    private static final String TABLE_NAME = "stationtime";//name for the table

    private static final String Station = "station";
    private static final String Time = "time";
    private static final String Line = "line";

    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        //Query to create table in databse
        String CREATE_CONTACTS_TABLE = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(" + Station + " TEXT," + Time + " TEXT," + Line + " TEXT);";
        db.execSQL(CREATE_CONTACTS_TABLE);
    }

    //Executes once a database change is occurred
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }

    //method to add row to table
    void addToLine1(DatabaseModel m) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues values = new ContentValues();

        values.put(Station, m.getStation());

        values.put(Time, m.getTime());

        values.put(Line, m.getLine());


        db.insert(TABLE_NAME, null, values);
        db.close();
    }

    public void insertIntoDB(String station,String time,String line) {
        // 1. get reference to writable DB
        SQLiteDatabase db1 = this.getWritableDatabase();

        // 2. create ContentValues to add key "column"/value
        ContentValues values = new ContentValues();
        values.put("station", station);
        values.put("time", time);
        values.put("line", line);

        // 3. insert
        db1.insert(TABLE_NAME, null, values);
        // 4. close
        db1.close();
    }

    //method to list all details from table
    public List<DatabaseModel> getAllUsers() {
        List<DatabaseModel> contactList = new ArrayList<DatabaseModel>();
        String selectQuery = "SELECT " + Time + " FROM " + TABLE_NAME + ";";//retrieve data from the database
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);

        cursor.moveToFirst();
        if (cursor.getCount()>0) {
            do {
                DatabaseModel m = new DatabaseModel();
                //                m.setStation(cursor.getString(0));
                m.setTime(cursor.getString(1));
                //              m.setLine(cursor.getString(2));
                contactList.add(m);
            } while (cursor.moveToNext());
        }
        return contactList;
    }
}

а также DatabaseModel.java:

public class DatabaseModel {
    String station, time, line;

    public DatabaseModel() {
    }

    public DatabaseModel(String station, String time, String line) {
        this.station = station;
        this.time = time;
        this.line = line;
    }

    public String getStation() {
        return station;
    }

    public void setStation(String station) {
        this.station = station;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getLine() {
        return line;
    }

    public void setLine(String line) {
        this.line = line;
    }
}

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

при использовании rawQuery, Строка SQL не должна быть; прекращено , но в ваших кодах:

String selectQuery = "SELECT " + Time + " FROM " + TABLE_NAME + ";"; 

, который должен быть:

String selectQuery = "SELECT " + Time + " FROM " + TABLE_NAME; 
0 голосов
/ 18 сентября 2018

Не удалось прочитать строку 0, столбец 1 из CursorWindow, которое имеет 17 строк, 1 столбец.

Я думаю, что ваша проблема на самом деле в строке DatabaseHelper.java строка 89, который, я думаю, будет m.setTime(cursor.getString(1));

В частности, ошибочная часть должна быть cursor.getString(1)

Запущенный вами запрос имеет только один столбец, индекс которого должен быть 0 вместо 1.

Есть более простой способ не попасть в эту проблему.Вы можете получить доступ к столбцам по имени.

cursor.getString(cursor.getColumnIndex(String columnName));

Поскольку Time содержит имя поля time, в этом случае это будет:

cursor.getString(cursor.getColumnIndex(Time));

Здесь вы передаете Time в качестве имени столбцаи он должен вернуть правильный столбец.

ВЫПУСК 2

изменение ошибки на: java.lang.NullPointerException: Попытка вызвать виртуальный метод 'void ir.shirazmetro.views.adapters.DataAdapter.notifyDataSetChanged () 'для ссылки на пустой объект

Проверьте в Fragment, инициализация mAdapter находится в нижней части метода, после того как вызапустите запрос и позвоните mAdapter.notifyDataSetChanged();.

. Вот почему вы получаете NPE.Если вы установите точку останова в этой строке, вы увидите, что mAdapter равно нулю.

Если возможно, инициализируйте адаптер (mAdapter = new DataAdapter(mActivity, LineList);) в методе Fragment onCreate().

Вместо передачи mActivity, вы можете вызвать Fragment getActivity();

Кстати, я думаю, mActivity никогда не устанавливается.Fragments может быть сложно в отношении деятельности.Я бы удалил эту ссылку и всегда зависел бы от вызова getActivity() во фрагменте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...