【发布时间】:2017-09-18 20:01:27
【问题描述】:
我的应用在 3 个不同的模拟器(api 16、21、24 和 25)上运行良好,但在真实设备上测试时一直崩溃。我收到这些错误消息。但由于我是 android 编程新手,我不太明白它们的含义。我正在使用 RecycleView。最后调用的方法是调用 swapCursor 方法的 onloadfinished 方法。谢谢你的帮助。
09-18 23:41:30.699 8324-8324/com.a2sigma.workermanager E/CursorWindow:
Failed to read row 0, column 0 from a CursorWindow which has 0 rows, 45 columns.
09-18 23:41:30.706 8324-8324/com.a2sigma.workermanager D/AndroidRuntime: Shutting down VM
09-18 23:41:30.719 8324-8324/com.a2sigma.workermanager E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.a2sigma.workermanager, PID: 8324
java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
at android.database.CursorWindow.nativeGetLong(Native Method)
at android.database.CursorWindow.getLong(CursorWindow.java:524)
at android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:75)
at android.database.CursorWrapper.getLong(CursorWrapper.java:127)
at com.a2sigma.workermanager.CursorRecyclerViewAdapter.onBindViewHolder(CursorRecyclerViewAdapter.java:56)
at com.a2sigma.workermanager.CursorRecyclerViewAdapter.onBindViewHolder(CursorRecyclerViewAdapter.java:16)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6400)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6433)
at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5377)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5640)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5482)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5478)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2215)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1542)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1502)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:595)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3625)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3354)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3886)
at android.view.View.layout(View.java:18874)
at android.view.ViewGroup.layout(ViewGroup.java:5954)
at android.support.constraint.ConstraintLayout.onLayout(ConstraintLayout.java:1197)
at android.view.View.layout(View.java:18874)
at android.view.ViewGroup.layout(ViewGroup.java:5954)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:18874)
at android.view.ViewGroup.layout(ViewGroup.java:5954)
at android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:131)
at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1389)
at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:868)
at android.view.View.layout(View.java:18874)
at android.view.ViewGroup.layout(ViewGroup.java:5954)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:18874)
at android.view.ViewGroup.layout(ViewGroup.java:5954)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
at android.view.View.layout(View.java:18874)
at android.view.ViewGroup.layout(ViewGroup.java:5954)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:18874)
at android.view.ViewGroup.layout(ViewGroup.java:5954)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
at android.view.View.layout(View.java:18874)
09-18 23:41:30.720 8324-8324/com.a2sigma.workermanager E/AndroidRuntime: at android.view.ViewGroup.layout(ViewGroup.java:5954)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:910)
at android.view.View.layout(View.java:18874)
at android.view.ViewGroup.layout(ViewGroup.java:5954)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2697)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2413)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1550)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7190)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:959)
at android.view.Choreographer.doCallbacks(Choreographer.java:734)
at android.view.Choreographer.doFrame(Choreographer.java:670)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:945)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
我的适配器类
package com.a2sigma.workermanager;
import android.database.Cursor;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.TextView;
class CursorRecyclerViewAdapter extends
RecyclerView.Adapter<CursorRecyclerViewAdapter.WorkerViewHolder> {
private static final String TAG = "CursorRecyclerViewAdapt";
private Cursor mCursor;
private OnTaskClickListener mListener;
interface OnTaskClickListener {
void onEditClick(Worker worker);
void onDeleteClick(Worker worker);
void onWorkerClick(Worker worker);
}
CursorRecyclerViewAdapter(Cursor cursor, OnTaskClickListener listener) {
Log.d(TAG, "CursorRecyclerViewAdapter: Constructor called");
mCursor = cursor;
mListener = listener;
}
@Override
public WorkerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.d(TAG, "onCreateViewHolder: new view requested");
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.worker_list_items, parent,false);
return new WorkerViewHolder(view);
}
@Override
public void onBindViewHolder(WorkerViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder: starts position " +position );
if((mCursor == null)||(mCursor.getCount() == 0)){
Log.d(TAG, "onBindViewHolder: providing instructions");
holder.name.setText(R.string.instructions_heading);
holder.noIndukKaryawan.setText(R.string.instructions);
holder.editButton.setVisibility(View.GONE);
holder.deleteButton.setVisibility(View.GONE);
}else {
if(!mCursor.moveToPosition(position)){
throw new IllegalStateException("Couldn't move cursor to position " +position);
}
Log.d(TAG, "onBindViewHolder: Hallooooooooo");
final Worker worker = new Worker(mCursor.getLong(mCursor.getColumnIndex(WorkersContract.Columns._ID)),
mCursor.getString(mCursor.getColumnIndex(WorkersContract.Columns.NAMA_KARYAWAN)),
mCursor.getString(mCursor.getColumnIndex(WorkersContract.Columns.JENIS_KELAMIN)),
mCursor.getString(mCursor.getColumnIndex(WorkersContract.Columns.TGL_LAHIR)),
mCursor.getString(mCursor.getColumnIndex(WorkersContract.Columns.TEMPAT_LAHIR)),
mCursor.getString(mCursor.getColumnIndex(WorkersContract.Columns.NKTP)),
mCursor.getString(mCursor.getColumnIndex(WorkersContract.Columns.NO_HP_1)),
mCursor.getString(mCursor.getColumnIndex(WorkersContract.Columns.NO_HP_2)),
mCursor.getString(mCursor.getColumnIndex(WorkersContract.Columns.NO_KK)),
mCursor.getString(mCursor.getColumnIndex(WorkersContract.Columns.IBU_KANDUNG)),
mCursor.getBlob(mCursor.getColumnIndex(WorkersContract.Columns.FOTO)));
Log.d(TAG, "onBindViewHolder: worker id "+ worker.getId());
holder.name.setText(worker.getmName());
holder.noIndukKaryawan.setText("NIK: " + worker.getmNIK());
holder.editButton.setVisibility(View.VISIBLE);//TODO add onClick listener
holder.deleteButton.setVisibility(View.VISIBLE); //TODO add onClick Listener
View.OnClickListener buttonListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "onClick: starts");
switch (view.getId()){
case R.id.wli_edit:
if(mListener != null){
mListener.onEditClick(worker);
}
break;
case R.id.wli_delete:
if(mListener!=null){
mListener.onDeleteClick(worker);
}
break;
default:
Log.d(TAG, "onClick: found unexpected button id");
}
}
};
holder.editButton.setOnClickListener(buttonListener);
holder.deleteButton.setOnClickListener(buttonListener);
}
}
@Override
public int getItemCount() {
Log.d(TAG, "getItemCount: starts");
if((mCursor == null) || (mCursor.getCount() == 0)){
return 1; // fib, because we populate a single viewHolder with instructions
}else {
return mCursor.getCount();
}
}
/**
* Swap in a new Cursor, returning the old Cursor.
* The returned old Cursor is <em>not</em> closed.
*
* @param newCursor The new cursor to be used
* @return Returns the previously set Cursor, or null if there wasn't one.
* If the given new Cursor is the same instance as the previously set
* Cursor, null is also returned.
*/
Cursor swapCursor(Cursor newCursor){
Log.d(TAG, "swapCursor: Called");
if(newCursor == mCursor){
return null;
}
final Cursor oldCursor = mCursor;
mCursor = newCursor;
if(newCursor !=null){
// notify the observers about the new cursor
notifyDataSetChanged();
}else {
// notify the obeservers about the lack of a data set
notifyItemRangeRemoved(0, getItemCount());
}
return oldCursor;
}
static class WorkerViewHolder extends RecyclerView.ViewHolder{
private static final String TAG = "TaskViewHolder";
TextView name = null;
TextView noIndukKaryawan = null;
ImageButton editButton = null;
ImageButton deleteButton = null;
public WorkerViewHolder(View itemView){
super(itemView);
Log.d(TAG, "TaskViewHolder: starts");
this.name = (TextView) itemView.findViewById(R.id.wli_name);
this.noIndukKaryawan = (TextView)itemView.findViewById(R.id.wli_nik);
this.editButton = (ImageButton) itemView.findViewById(R.id.wli_edit);
this.deleteButton = (ImageButton) itemView.findViewById(R.id.wli_delete);
}
}
}
XML 文件 1.worker_list_items
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/wli_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="16dp"
android:textColor="?android:attr/textColorPrimary"
android:textSize="22sp"
android:textStyle="bold"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/wli_edit"
app:layout_constraintTop_toTopOf="parent"
tools:text="Nama Karyawan" />
<TextView
android:id="@+id/wli_nik"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="1dp"
android:textColor="?android:attr/textColorSecondary"
android:textSize="18sp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/wli_edit"
app:layout_constraintTop_toBottomOf="@+id/wli_name"
tools:text="123.256.478" />
<ImageButton
android:id="@+id/wli_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="16dp"
android:contentDescription="@string/delete_button"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@android:drawable/ic_menu_delete" />
<ImageButton
android:id="@+id/wli_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="0dp"
android:contentDescription="@string/edit_button"
app:layout_constraintRight_toLeftOf="@+id/wli_delete"
app:layout_constraintTop_toTopOf="@+id/wli_delete"
app:srcCompat="@android:drawable/ic_menu_edit" />
</android.support.constraint.ConstraintLayout>
还有 RycycleView XML 文件
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/worker_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp" />
</android.support.constraint.ConstraintLayout>
【问题讨论】:
-
看起来这不是整个堆栈跟踪...你能发布整个堆栈跟踪吗?
-
您的 xml 中的
RecyclerView中有android:animateLayoutChanges="true"吗? -
@MosesAprico 不,我没有,我编辑了我的问题。
-
@10101010 其实我只有这些
-
哇,现在是凌晨 4 点,哈哈。顺便说一句,您是否尝试过使用断点进行调试?它通常显示像这样奇怪的事情的问题。
标签: android android-layout view android-recyclerview