【问题标题】:RXJAVA ROOM androidRXJAVA ROOM 安卓
【发布时间】:2020-01-01 04:21:24
【问题描述】:

尝试学习 Room 和 RXJAVA。 我已经理解了其中大约 80% 的内容,但我一直无法弄清楚其余部分。

这是我在插入数据时遇到的错误。

java.lang.NullPointerException:尝试调用接口方法 '空白 com.example.learnroom.EntityDao.insert(com.example.learnroom.Entitys)' 在空对象引用上

如果我不运行 try catch,我会收到以下似乎相关的错误。

java.lang.RuntimeException:无法启动活动 组件信息{com.example.learnroom/com.example.learnroom.MainActivity}: java.lang.NullPointerException:尝试调用接口方法 'io.reactivex.也许 com.example.learnroom.EntityDao.getEntity(java.lang.String)' 为空 对象引用

我该如何解决这个问题?

我已经尝试将网络上大多数使用 recyclerviews 的教程简化为仅 2 个文本字段。他们说这是 3 件,但看起来不像,因为数据库从未设置过,所以我以一种运行代码的方法运行它。也许有人可以帮我解释一下这是如何工作的。 我的代码

public interface EntityDao {

 @Query("SELECT * FROM Entitys WHERE ID  = :ID LIMIT 1")
Maybe<List<Entitys>> getEntity(String ID);

@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(Entitys entitys);

@Query("DELETE FROM Entitys")
void deleteAllEntity();
}

实体

 public class Entitys {

@PrimaryKey
@NonNull
public String ID;

public  String ts;
public  String tss;

public Entitys(@NonNull String ID, String ts, String tss) {
    this.ID = ID;
    this.ts = ts;
    this.tss = tss;
}

public String getTss() {
    return tss;
}

public void setTss(String tss) {
    this.tss = tss;
}

public void setID(String ID) {
    this.ID = ID;
}

public void setTs(String ts) {
    this.ts = ts;
}

public String getID() {
    return ID;
}

public String getTs() {
    return ts;
}
 } 

数据库

 @Database(entities = {Entitys.class}, version = 1)
 public abstract class PathwaysDB extends RoomDatabase {

private static volatile PathwaysDB INSTANCE;

public static EntityDao entityDao() {
    return null;
}

public static PathwaysDB getInstance(Context context) {
    if (INSTANCE == null) {
        synchronized (PathwaysDB.class) {
            if (INSTANCE == null) {
                INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                        PathwaysDB.class, "Pathwaysdb")
                        .build();
            }
        }
    }
    return INSTANCE;
}


 }

主活动

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private static final String TAG = MainActivity.class.getSimpleName();
Button tb;
EditText te, tes;
String ts, tss, ID;

CompositeDisposable compositeDisposable = new CompositeDisposable();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ID ="test";
    te = findViewById(R.id.te);

    tb = findViewById(R.id.tb);
    tb.setOnClickListener(this);

    tes = findViewById(R.id.tes);

    Builddb();

    try{
    getData();}catch (Exception e){}
}

   private void Builddb() {

    Completable.fromAction(() -> PathwaysDB.getInstance(this))
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new CompletableObserver() {
                @Override
                public void onSubscribe(Disposable d) {
                    compositeDisposable.add(d);
                }

                @Override
                public void onComplete() {
                    // action was completed successfully
                }

                @Override
                public void onError(Throwable e) {
                    // something went wrong
                }
            });
}

private void getData() {

    Maybe<List<Entitys>> single = entityDao().getEntity(ID);
    single.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new MaybeObserver<List<Entitys>>() {
                @Override
                public void onSubscribe(Disposable d) {
                    // add it to a CompositeDisposable
                }

                @Override
                public void onSuccess(List<Entitys> entity) {
                    te.setText(entity.indexOf(ts));
                    tes.setText(entity.indexOf(tss));
                }
                @Override
                public void onError(Throwable e) {
                    // show an error message
                }

                @Override
                public void onComplete() {
                }
            });

    compositeDisposable.add((Disposable) single);
}

@Override
protected void onDestroy() {
    super.onDestroy();

    compositeDisposable.dispose();
}

private void updateUserName() {

   ts = te.getText().toString();
   tss = tes.getText().toString();
   Entitys entitys = new Entitys(ID, ts, tss);

    Completable.fromAction(() -> entityDao().insert(entitys))
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new CompletableObserver() {
                @Override
                public void onSubscribe(Disposable d) {
                    compositeDisposable.add(d);
                }

                @Override
                public void onComplete() {
                    // action was completed successfully
                }

                @Override
                public void onError(Throwable e) {
                    // something went wrong
                }
            });


}

@Override
public void onClick(View view) {
    updateUserName();

    Intent forward = new Intent(this, secondpage.class);
    startActivity(forward);
}
 }

【问题讨论】:

  • NullPointerException 因为从entityDao()返回null
  • 请不要将您的问题编辑为答案。我已将此回滚到修订版 #2,这是最后一个好的问题状态。非常欢迎您自行回答 - 您可以查看您的回答材料的文本in the revision history

标签: android android-room rx-android


【解决方案1】:

崩溃的原因是您的 PathwaysDB 类中的这一行

public static EntityDao entityDao() {
return null;
}

它返回空值。应该是这样的

public abstract EntityDao entityDao()

【讨论】:

  • 感谢您的帮助。如果我按照建议更改代码,我将无法编译。以下错误错误:找不到符号方法 entityDao() 方法 entityDao() 应该是什么?
  • 问题出在这里 Maybe> single = entityDao().getEntity(ID);和 Completable.fromAction(() -> entityDao().insert(entitys)) 我试图将数据库作为 PathwaysDB.entityDao() 放在前面,但它告诉我不能引用非静态方法来自静态上下文。
  • 你必须使用你的类实例,即你可以使用 PathwaysDb.getInstance(context).entityDao()。而且你必须使用正确的上下文。在活动中,您可以使用活动上下文。
  • 我认为是 getApplicationContext() 丢失了,因为我不再收到该错误并且应用程序继续运行。谢谢你。我一直在放这个。和class.this。不过,我仍然对返回填充字段的数据有疑问。稍后我将发布收益
  • 我想出了最后一部分更改了上面的代码。感谢你们的时间和精力。感谢您帮助我学习。
【解决方案2】:

您忘记将@Dao annonation 添加到您的EntityDao 接口类。 您还需要更改以下方法:

public static EntityDao entityDao() {
    return null;
}

public abstract EntityDao entityDao();

【讨论】:

  • @dao 在顶部,只是这里没有图片我忘记了剪辑,但是过去它在那里
  • 在添加上述抽象方法后,您是否尝试过重建项目?
  • 是的,我试过了。没有。我可能会抹去这一切,然后重新开始。有什么不对劲。我在一个地方读到将数据库放在一个单例中以确保它只有一个实例。但是所有这些教程都没有这样做。
  • 请提供答案和解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多