【发布时间】:2020-09-27 12:43:34
【问题描述】:
所以我正在创建一个使用回收器视图来显示卡片视图组件的应用程序,但问题是当我使用RecyclerView groceryRecycler = (RecyclerView) findViewById (R.id.recycler_view1) 时收到空指针异常。对我来说没有意义的是我正在为 groceryRecycler 变量引用正确的回收器视图布局。
我已经对空指针异常进行了研究,它仅在您声明变量但未为其分配对象时发生。但我确实使用findViewById () 为回收站视图变量分配了一个对象。结果,每当我在回收器视图变量上调用一个方法时,我都会得到一个空指针异常。我不明白我在这里做错了什么或如何解决问题,任何帮助将不胜感激。
这是我的回收站视图布局代码:
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recycler_view1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" >
</androidx.recyclerview.widget.RecyclerView>
这是我实例化回收器视图的代码:
package com.myapp.groceryapp;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
public class GroceryItem extends AppCompatActivity {
MyDatabaseHelper databaseHelper = new MyDatabaseHelper(this);
SQLiteDatabase db;
Cursor cursor;
RecyclerView groceryRecycler;
private static final int STORAGE_PERMISSION_CODE = 101;
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grocery_item);
askForPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, STORAGE_PERMISSION_CODE);
Log.d ("red", "onCreate has ran");
StartDatabase sd = new StartDatabase();
sd.execute(databaseHelper);
}
public void startIntent () {
Intent intent = new Intent (this, Faan.class);
}
public void accessDataBase () {
try {
db = databaseHelper.getReadableDatabase();
cursor = db.query ("GROCERY_TABLE", new String[] {"NAME", "PATHS"}, null, null, null, null, null);
db.close();
} catch (SQLiteException e) {
e.printStackTrace();
}
Log.d ("red", "accessDataBase has ran");
}
public void createRecyclerView () {
GridLayoutManager layoutManager = new GridLayoutManager(GroceryItem.this, 2, GridLayoutManager.VERTICAL, false);
GroceryAdapter adapter = new GroceryAdapter (GroceryItem.this, cursor);
groceryRecycler = (RecyclerView) findViewById(R.id.recycler_view1);
if (groceryRecycler == null) {
Log.d ("red", "grocery recylcerview is null");
}
groceryRecycler.setLayoutManager(layoutManager);
groceryRecycler.setAdapter (adapter);
Log.d ("red", "createRecyclerView has ran");
}
public void askForPermission (String permission, int requestCode) {
if (isStoragePermissionGranted()) {
ActivityCompat.requestPermissions(this, new String [] {permission}, requestCode);
} else {
Toast.makeText (this, "Permission already granted", Toast.LENGTH_SHORT)
.show();
}
}
public void onRequestPermissionsResult (int requestCode, String [] permissions, int [] grantResults) {
super.onRequestPermissionsResult (requestCode, permissions, grantResults);
if (requestCode == STORAGE_PERMISSION_CODE) {
if (grantResults.length > 0 && grantResults [0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Storage Permission Granted", Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(this, "Storage Permission Denied", Toast.LENGTH_SHORT)
.show();
}
}
}
public boolean isStoragePermissionGranted () {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "permission granted", Toast.LENGTH_SHORT)
.show();
return true;
}
return false;
}
private class StartDatabase extends AsyncTask<MyDatabaseHelper, Void, Boolean> {
protected void onPreExecute () {}
@Override
protected Boolean doInBackground(MyDatabaseHelper... myDatabaseHelpers) {
try {
accessDataBase();
Log.d ("red", "doInBackground has ran");
return true;
} catch (SQLiteException e) {
Log.d ("red", "doInBackground has ran");
return false;
}
}
protected void onPostExecute (Boolean success) {
createRecyclerView();
adapter.setOnItemClickListener(new GroceryAdapter.OnItemClickListener() {
@Override
public void onItemClick(int position) {
startIntent();
}
});
if (!success) {
Toast toast = Toast.makeText(GroceryItem.this, "Database unavailable", Toast.LENGTH_SHORT);
toast.show();
}
Log.d ("red", "onPostExcecute has ran");
}
}
}
这是我收到的异常:
java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.recyclerview.widget.RecyclerView.setLayoutManager(androidx.recyclerview.widget.RecyclerView$LayoutManager)' on a null object reference
at com.myapp.groceryapp.GroceryItem.createRecyclerView(GroceryItem.java:70)
at com.myapp.groceryapp.GroceryItem$StartDatabase.onPostExecute(GroceryItem.java:131)
at com.myapp.groceryapp.GroceryItem$StartDatabase.onPostExecute(GroceryItem.java:112)
at android.os.AsyncTask.finish(AsyncTask.java:755)
at android.os.AsyncTask.access$900(AsyncTask.java:192)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:772)
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)
【问题讨论】:
-
你从哪里调用 createRecyclerView?
-
我从asyncTask中的onPostExecute()调用createRecyclerView()
-
可能的原因是,您启动的异步任务在您的 setconteview() 完成工作之前就完成了。 (请提及您从哪里开始异步任务)
-
@vishnu 哦,你也许是对的,也许 asynctask 线程在主线程之前完成了,但是,我将如何确认或解决问题?感谢您的帮助
-
异步任务完成后无需运行任何代码。在 onCreate 中设置回收器,然后保留对适配器的引用。使用异步调用完成时的结果更新适配器的数据
标签: java android android-recyclerview nullpointerexception findviewbyid