在访问游标中的数据之前,请确保已正确初始化游标.如何解决它?



我想在活动内部的片段中显示我从SQLite DB到RecyclerView的数据。 iget 错误 in line:contactList.add(m(; 在 Databese 帮助程序 getAllUsers 方法中。

这是我的日志猫:

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

这是我的代码:

活动.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) {
}
});
}
}

这是数据适配器.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) {
}
}

这是我的数据助手.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;
}
}

以及数据库模型.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;
}
}

无法从具有 17 行的 CursorWindow 读取第 0 行第 1 列, 1 列。

我认为您遇到的问题实际上符合DatabaseHelper.java89,我想这将是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:尝试调用 虚拟方法'无效 ir.shirazmetro.views.adapters.DataAdapter.notifyDataSetChanged((' on a 空对象引用

Fragment中签到,mAdapter的初始化在方法的底部,运行查询并调用mAdapter.notifyDataSetChanged();之后。

这就是为什么你会得到NPE.如果在该行上放置断点,您将看到mAdapter为 null。

如果可能的话,在FragmentonCreate()方法中初始化适配器(mAdapter = new DataAdapter(mActivity, LineList);(。

与其传递mActivity,不如调用FragmentgetActivity();

顺便说一下,我认为mActivity永远不会设置。Fragments活动可能会很棘手。我会删除该引用,并始终依赖于在片段中调用getActivity()

使用rawQuery时,SQL 字符串不得被 ; 终止,但在你的代码中:

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

应该是:

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

最新更新