我的应用程序不断崩溃,光标未正确初始化

Posted

技术标签:

【中文标题】我的应用程序不断崩溃,光标未正确初始化【英文标题】:My app keeps crashing, Cursor is not initialized correctly 【发布时间】: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_
android:layout_
android:orientation="vertical">

<TextView
    android:id="@+id/wli_name"
    android:layout_
    android:layout_
    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_
    android:layout_
    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_
    android:layout_
    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_
    android:layout_
    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_
android:layout_>

<android.support.v7.widget.RecyclerView
    android:id="@+id/worker_list"
    android:layout_
    android:layout_
    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 点,哈哈。顺便说一句,您是否尝试过使用断点进行调试?它通常显示像这样奇怪的事情的问题。 【参考方案1】:

这通常是通货膨胀错误。您需要比较您尝试填充的 View ID,确保它们不为空,并且您已正确设置 Recycler View Holder Adapter。

发布您的适配器、您要填充的行的 xml、您的查看器模式以及您的适配器设置和分配,我们当然可以帮助您解决问题。

只是为了更新答案,您的光标应该在访问之前正确填充,并且您应该在访问之前确保内容存在。

填充光标的示例

    Cursor cursor = null;
        try 
            cursor = queryBuilder.query(mysqlDBHelper.openDatabase(<YOUR CONTEXT>), projection, selection, selectionArgs, null, null, sortOrder);

         catch (Exception e) 
            e.printStackTrace();
        
return cursor;

接下来,当您决定从光标访问值时,您可以进行一些安全检查,而不是直接访问它们。它可能会变得相当冗长,所以我建议创建一个从光标创建对象的方法,然后在那里进行所有的 null 安全检查。

代替:

mCursor.getString(mCursor.getColumnIndex(WorkersContract.Columns.IBU_KANDUNG)));

执行以下操作:

int IBU_KANDUNG_INDEX = mCursor.getColumnIndex(WorkersContract.Columns.IBU_KANDUNG);
myObject.setString(mCursor.getString(IBU_KANDUNG_INDEX) == null ? "" : mCursor.getString(IBU_KANDUNG_INDEX));

这将确保您不会在对象中设置空值或尝试访问空游标的 -1 索引。

【讨论】:

感谢您的快速回复,我已使用 xml 和适配器类编辑了我的问题。 抱歉,本可以在这里回复,您能否为我提供更多关于错误方面的信息。充气机错误基本上无法创建您的 UI 元素,但有一个根本原因。可能是交换游标在绘制第一行时发生或其他一百万个原因,但我确信这些日志中嵌套了更多信息,也许我们可以找到它:) 嗯,这有帮助。完美的。所以你有一个有效的游标对象,但它是空的。您正在崩溃,因为您的光标内容未从数据库中正确填充。因此,无论您从何处创建游标(通常在某种 contentProvider 中,您的格式设置不正确或可能在 SQL 中遇到错误。无论如何,您的游标没有数据库内容,因此 getString 会使您的尝试填充 UI 元素的应用程序。

以上是关于我的应用程序不断崩溃,光标未正确初始化的主要内容,如果未能解决你的问题,请参考以下文章

尝试访问 android 应用程序中的联系人不断崩溃

由于 Firebase 初始化,App Delegate 崩溃

Lateinit 属性未在 Fragment 上初始化

UIViewControllerHierarchyInconsistency 错误 - 应用程序不断崩溃

Mac 应用程序在启动时崩溃,链接框架未捆绑

我的启动画面后我的程序不断崩溃。为啥?