如何解决使用异步任务时,光标变为空?
我有一个数据库代码,该数据库代码从表中获取数据并将其存储到游标中,但是当我打开在回收站视图上显示数据的活动时,在主线程上运行数据库代码会使我的应用变慢。因此,我将数据库代码移至asyntask内部类并尝试运行它。
但是,在asyntask在onCreate ()
中运行之后,我的回收器视图适配器代码运行了,并且由于游标为空,在游标对象上调用的getItemCount ()
引发了null pointer exception
。
从调试中,我发现游标变为null的位置,但不明白为什么它变为null。 accessDatabase ()
运行时的游标不为null,但是asynctask内部类在onCreate ()
中运行后,游标变为null。
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();
}
}
}
}
public void accessDataBase () {
try {
db = databaseHelper.getReadableDatabase();
cursor = db.query ("GROCERY_DATA",new String[] {"NAME","PATHS"},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)
解决方法
将其设为null的原因之一是由于错误的假设,即Main线程正在等待异步任务完成。那当然是错误的(否则,您将不需要其他线程)。您有不同的解决方案,例如:
-
使用CursorLoader(已弃用) -
AsyncTask(已弃用)完成加载游标后,使用回调通知UI线程。 here 示例
- 研究另一种技术,例如coroutines
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。