当我使用异步任务时,我的游标变为空?

bjp0bcyl  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(373)

我有一个数据库代码,它从我的表中获取数据并将其存储到我的游标中,但是当我打开在回收器视图中显示数据的活动时,在主线程上运行数据库代码会减慢我的应用程序的速度。因此,我将数据库代码移到asyntask内部类并尝试运行它。
但是,在asyntask在 onCreate () 我的回收器视图适配器代码运行 getItemCount () 在cursor对象上调用 null pointer exception 因为游标为空。
通过调试,我发现了游标变为null的地方,但不明白它为什么变为null。当 accessDatabase () runs不为null,但在中运行asynctask内部类之后 onCreate () 光标变为空。
oncreate方法中的代码:

protected void onCreate (Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.item_grocery);

    RecyclerView groceryRecycler = (RecyclerView) findViewById(R.id.grocery_recycler_view);

    StartDatabase sd = new StartDatabase();
    sd.execute(databaseHelper);
    Log.d ("blue", "sd has ran");

    if (cursor == null) {
        Log.d ("green", "cursor is null");//I receive this in the log cat
    }

    captionedImagesAdapter adapter = new captionedImagesAdapter (this, cursor);
    GridLayoutManager layoutManager = new GridLayoutManager(this, 2, GridLayoutManager.VERTICAL, false);
    groceryRecycler.setLayoutManager(layoutManager);
    groceryRecycler.setAdapter (adapter);
}

异步任务内部类:

private class StartDatabase extends AsyncTask<MyDatabaseHelper, Void, Boolean> {

    protected void onPreExecute () {}

    @Override
    protected Boolean doInBackground(MyDatabaseHelper... myDatabaseHelpers) {
        try {
            accessDataBase();

            return true;
        } catch (SQLiteException e) {
            return false;

        }
    }

    protected void onPostExecute (Boolean success) {
        if (!success) {
            Toast toast = Toast.makeText(grocery_item.this, "Database unavailable", Toast.LENGTH_SHORT);
            toast.show();
        }

        }
    }
}

access数据库方法:

public void accessDataBase () {

    try {

        db = databaseHelper.getReadableDatabase();

        cursor = db.query ("GROCERY_DATA", new String[] {"NAME", "PATHS"}, null, null, null, null, null);

        if (cursor == null) {
            Log.d ("blue", "cursor is null");
        }

    } catch (SQLiteException e) {
        e.printStackTrace();
    }

}

我的循环视图适配器:

public class captionedImagesAdapter extends RecyclerView.Adapter <captionedImagesAdapter.ViewHolder> {

private Context context;
private Cursor cursor;

public captionedImagesAdapter (Context context, Cursor cursor) {
    this.context = context;
    this.cursor = cursor;

    if (this.cursor == null) {
        Log.d ("red", "cursor is null");//I receive this in the log cat 
    }
}

public captionedImagesAdapter.ViewHolder onCreateViewHolder (ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(context);
    CardView cv = (CardView) inflater.inflate(R.layout.card_view, parent, false);

    return new ViewHolder (cv);
}

public void onBindViewHolder(ViewHolder holder, int position) {
    if (!cursor.moveToPosition(position)) {
        return;
    }

    String info_text = cursor.getString (0);
    holder.textView.setText(info_text);

    String image_Path = cursor.getString(1);
    File file = new File (image_Path);

    if (file.exists()) {

        Bitmap bitmap = BitmapFactory.decodeFile (file.getAbsolutePath());

        holder.imageView.setImageBitmap(bitmap);
    }
}

public int getItemCount() {
    return cursor.getCount();//Line throwing the exception
}

public static class ViewHolder extends RecyclerView.ViewHolder {
    private ImageView imageView;
    private TextView textView;

    public ViewHolder(CardView view) {
        super(view);
        imageView = view.findViewById(R.id.info_image);
        textView = view.findViewById(R.id.info_text);
    }
}

}
我收到的例外情况是:

java.lang.NullPointerException: Attempt to invoke interface method 'int android.database.Cursor.getCount()' on a null object reference
    at com.myapps.myapplication.captionedImagesAdapter.getItemCount(captionedImagesAdapter.java:58)
    at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:4135)
    at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3939)
    at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4499)
    at android.view.View.layout(View.java:22085)
    at android.view.ViewGroup.layout(ViewGroup.java:6290)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
    at android.view.View.layout(View.java:22085)
    at android.view.ViewGroup.layout(ViewGroup.java:6290)
    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
    at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
    at android.view.View.layout(View.java:22085)
    at android.view.ViewGroup.layout(ViewGroup.java:6290)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
    at android.view.View.layout(View.java:22085)
    at android.view.ViewGroup.layout(ViewGroup.java:6290)
    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
    at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
    at android.view.View.layout(View.java:22085)
    at android.view.ViewGroup.layout(ViewGroup.java:6290)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
    at com.android.internal.policy.DecorView.onLayout(DecorView.java:786)
    at android.view.View.layout(View.java:22085)
    at android.view.ViewGroup.layout(ViewGroup.java:6290)
    at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:3333)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2810)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1930)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7988)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1154)
    at android.view.Choreographer.doCallbacks(Choreographer.java:977)
    at android.view.Choreographer.doFrame(Choreographer.java:893)
    at android.view.Choreographer$FrameHandler.handleMessage(Choreographer.java:1082)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7682)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
7y4bm7vi

7y4bm7vi1#

将其设为null的原因之一是,错误地假设主线程正在等待异步任务完成。当然,这是错误的(否则就不需要另一个线程了)。您有不同的选项来修复它,例如:
使用游标加载程序(已弃用)
当asynctask(已弃用)加载完游标时,使用回调通知ui线程。举个例子
研究一种不同的技术,比如协同程序

相关问题