【问题标题】:error: Not sure how to handle insert method's return type错误:不确定如何处理插入方法的返回类型
【发布时间】:2021-11-03 08:32:04
【问题描述】:

所以我尝试使用 Executor 在我的 android 应用程序中执行 Dao,但是当我创建 Executor 时,它说它要求正在运行的方法具有 Runnable 返回类型?

所以我让它们都返回 Runnable,但现在 Android Studio 给了我错误:

/database/TripDao.java:28: error: Not sure how to handle insert method's return type.
    Runnable insertTrip(Trip trip);
             ^

道:

import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;

import java.util.List;
import java.util.UUID;

@Dao
public interface TripDao {
    @Query("DELETE FROM trip")
    public void deleteTrips();

    @Query("SELECT * FROM trip")
    LiveData<List<Trip>> getAll();

    @Query("SELECT * FROM trip WHERE uuid=:id")
    public LiveData<Trip> getTrip(UUID id);

    @Delete
    Runnable delete(Trip trip);

    @Insert
    Runnable insertTrip(Trip trip);

    @Update
    Runnable updateTrip(Trip trip);


}

存储库:

package com.example.csc202assignment.database;

import android.content.Context;

import androidx.lifecycle.LiveData;
import androidx.room.Room;

import java.util.List;
import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;


public class TripRepository {
    private static TripRepository INSTANCE = null;
    private final String DATABASE_NAME = "trip-database";
    private Context context;
    TripDatabase database;
    static TripDao tripDao;
    Executor executor = Executors.newSingleThreadExecutor();

    private TripRepository(Context context) {
        this.context = context;
        this.database = Room.databaseBuilder(
                context.getApplicationContext(),
                TripDatabase.class,DATABASE_NAME).build();
         tripDao = database.tripDao();

    }

    void deleteTrips(){
        tripDao.deleteTrips();
    }

    void delete(Trip trip){
        executor.execute(tripDao.delete(trip));

    }

    void insertTrip(Trip trip){
        executor.execute(tripDao.insertTrip(trip));
    }

    void updateTrip(Trip trip){
        executor.execute(tripDao.updateTrip(trip));
    }

    public LiveData<List<Trip>> getAll(){ return tripDao.getAll();
    }

    public static LiveData<Trip> getTrip(UUID id){
        return tripDao.getTrip(id);
    }

    public static void initialise(Context context){
        if(INSTANCE==null){
            INSTANCE = new TripRepository(context);
        }
    }

     public static TripRepository get() throws IllegalStateException {
         try {
             return INSTANCE;
         } catch (IllegalStateException e) {
             System.out.println("TripRepository must be initialised");
         }
         return INSTANCE;
     }
}

Dao_Impl

package com.example.csc202assignment.database;

import android.database.Cursor;
import androidx.lifecycle.LiveData;
import androidx.room.EntityDeletionOrUpdateAdapter;
import androidx.room.EntityInsertionAdapter;
import androidx.room.RoomDatabase;
import androidx.room.RoomSQLiteQuery;
import androidx.room.SharedSQLiteStatement;
import androidx.room.util.CursorUtil;
import androidx.room.util.DBUtil;
import androidx.sqlite.db.SupportSQLiteStatement;
import java.lang.Class;
import java.lang.Exception;
import java.lang.Override;
import java.lang.Runnable;
import java.lang.String;
import java.lang.SuppressWarnings;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Callable;

@SuppressWarnings({"unchecked", "deprecation"})
public final class TripDao_Impl implements TripDao {
  private final RoomDatabase __db;

  private final EntityInsertionAdapter<Trip> __insertionAdapterOfTrip;

  private final TripTypeConverter __tripTypeConverter = new TripTypeConverter();

  private final EntityDeletionOrUpdateAdapter<Trip> __deletionAdapterOfTrip;

  private final EntityDeletionOrUpdateAdapter<Trip> __updateAdapterOfTrip;

  private final SharedSQLiteStatement __preparedStmtOfDeleteTrips;

  public TripDao_Impl(RoomDatabase __db) {
    this.__db = __db;
    this.__insertionAdapterOfTrip = new EntityInsertionAdapter<Trip>(__db) {
      @Override
      public String createQuery() {
        return "INSERT OR ABORT INTO `Trip` (`uuid`,`title`,`destination`,`date`,`duration`) VALUES (?,?,?,?,?)";
      }

      @Override
      public void bind(SupportSQLiteStatement stmt, Trip value) {
        final String _tmp;
        _tmp = __tripTypeConverter.fromUUID(value.uuid);
        if (_tmp == null) {
          stmt.bindNull(1);
        } else {
          stmt.bindString(1, _tmp);
        }
        if (value.title == null) {
          stmt.bindNull(2);
        } else {
          stmt.bindString(2, value.title);
        }
        if (value.destination == null) {
          stmt.bindNull(3);
        } else {
          stmt.bindString(3, value.destination);
        }
        if (value.date == null) {
          stmt.bindNull(4);
        } else {
          stmt.bindString(4, value.date);
        }
        if (value.duration == null) {
          stmt.bindNull(5);
        } else {
          stmt.bindString(5, value.duration);
        }
      }
    };
    this.__deletionAdapterOfTrip = new EntityDeletionOrUpdateAdapter<Trip>(__db) {
      @Override
      public String createQuery() {
        return "DELETE FROM `Trip` WHERE `uuid` = ?";
      }

      @Override
      public void bind(SupportSQLiteStatement stmt, Trip value) {
        final String _tmp;
        _tmp = __tripTypeConverter.fromUUID(value.uuid);
        if (_tmp == null) {
          stmt.bindNull(1);
        } else {
          stmt.bindString(1, _tmp);
        }
      }
    };
    this.__updateAdapterOfTrip = new EntityDeletionOrUpdateAdapter<Trip>(__db) {
      @Override
      public String createQuery() {
        return "UPDATE OR ABORT `Trip` SET `uuid` = ?,`title` = ?,`destination` = ?,`date` = ?,`duration` = ? WHERE `uuid` = ?";
      }

      @Override
      public void bind(SupportSQLiteStatement stmt, Trip value) {
        final String _tmp;
        _tmp = __tripTypeConverter.fromUUID(value.uuid);
        if (_tmp == null) {
          stmt.bindNull(1);
        } else {
          stmt.bindString(1, _tmp);
        }
        if (value.title == null) {
          stmt.bindNull(2);
        } else {
          stmt.bindString(2, value.title);
        }
        if (value.destination == null) {
          stmt.bindNull(3);
        } else {
          stmt.bindString(3, value.destination);
        }
        if (value.date == null) {
          stmt.bindNull(4);
        } else {
          stmt.bindString(4, value.date);
        }
        if (value.duration == null) {
          stmt.bindNull(5);
        } else {
          stmt.bindString(5, value.duration);
        }
        final String _tmp_1;
        _tmp_1 = __tripTypeConverter.fromUUID(value.uuid);
        if (_tmp_1 == null) {
          stmt.bindNull(6);
        } else {
          stmt.bindString(6, _tmp_1);
        }
      }
    };
    this.__preparedStmtOfDeleteTrips = new SharedSQLiteStatement(__db) {
      @Override
      public String createQuery() {
        final String _query = "DELETE FROM trip";
        return _query;
      }
    };
  }

  @Override
  public Runnable insertTrip(final Trip trip) {
    __db.assertNotSuspendingTransaction();
  }

  @Override
  public Runnable delete(final Trip trip) {
    __db.assertNotSuspendingTransaction();
  }

  @Override
  public Runnable updateTrip(final Trip trip) {
    __db.assertNotSuspendingTransaction();
  }

  @Override
  public void deleteTrips() {
    __db.assertNotSuspendingTransaction();
    final SupportSQLiteStatement _stmt = __preparedStmtOfDeleteTrips.acquire();
    __db.beginTransaction();
    try {
      _stmt.executeUpdateDelete();
      __db.setTransactionSuccessful();
    } finally {
      __db.endTransaction();
      __preparedStmtOfDeleteTrips.release(_stmt);
    }
  }

  @Override
  public LiveData<List<Trip>> getAll() {
    final String _sql = "SELECT * FROM trip";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
    return __db.getInvalidationTracker().createLiveData(new String[]{"trip"}, false, new Callable<List<Trip>>() {
      @Override
      public List<Trip> call() throws Exception {
        final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
        try {
          final int _cursorIndexOfUuid = CursorUtil.getColumnIndexOrThrow(_cursor, "uuid");
          final int _cursorIndexOfTitle = CursorUtil.getColumnIndexOrThrow(_cursor, "title");
          final int _cursorIndexOfDestination = CursorUtil.getColumnIndexOrThrow(_cursor, "destination");
          final int _cursorIndexOfDate = CursorUtil.getColumnIndexOrThrow(_cursor, "date");
          final int _cursorIndexOfDuration = CursorUtil.getColumnIndexOrThrow(_cursor, "duration");
          final List<Trip> _result = new ArrayList<Trip>(_cursor.getCount());
          while(_cursor.moveToNext()) {
            final Trip _item;
            _item = new Trip();
            final String _tmp;
            if (_cursor.isNull(_cursorIndexOfUuid)) {
              _tmp = null;
            } else {
              _tmp = _cursor.getString(_cursorIndexOfUuid);
            }
            _item.uuid = __tripTypeConverter.toUUID(_tmp);
            if (_cursor.isNull(_cursorIndexOfTitle)) {
              _item.title = null;
            } else {
              _item.title = _cursor.getString(_cursorIndexOfTitle);
            }
            if (_cursor.isNull(_cursorIndexOfDestination)) {
              _item.destination = null;
            } else {
              _item.destination = _cursor.getString(_cursorIndexOfDestination);
            }
            if (_cursor.isNull(_cursorIndexOfDate)) {
              _item.date = null;
            } else {
              _item.date = _cursor.getString(_cursorIndexOfDate);
            }
            if (_cursor.isNull(_cursorIndexOfDuration)) {
              _item.duration = null;
            } else {
              _item.duration = _cursor.getString(_cursorIndexOfDuration);
            }
            _result.add(_item);
          }
          return _result;
        } finally {
          _cursor.close();
        }
      }

      @Override
      protected void finalize() {
        _statement.release();
      }
    });
  }

  @Override
  public LiveData<Trip> getTrip(final UUID id) {
    final String _sql = "SELECT * FROM trip WHERE uuid=?";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1);
    int _argIndex = 1;
    final String _tmp;
    _tmp = __tripTypeConverter.fromUUID(id);
    if (_tmp == null) {
      _statement.bindNull(_argIndex);
    } else {
      _statement.bindString(_argIndex, _tmp);
    }
    return __db.getInvalidationTracker().createLiveData(new String[]{"trip"}, false, new Callable<Trip>() {
      @Override
      public Trip call() throws Exception {
        final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
        try {
          final int _cursorIndexOfUuid = CursorUtil.getColumnIndexOrThrow(_cursor, "uuid");
          final int _cursorIndexOfTitle = CursorUtil.getColumnIndexOrThrow(_cursor, "title");
          final int _cursorIndexOfDestination = CursorUtil.getColumnIndexOrThrow(_cursor, "destination");
          final int _cursorIndexOfDate = CursorUtil.getColumnIndexOrThrow(_cursor, "date");
          final int _cursorIndexOfDuration = CursorUtil.getColumnIndexOrThrow(_cursor, "duration");
          final Trip _result;
          if(_cursor.moveToFirst()) {
            _result = new Trip();
            final String _tmp_1;
            if (_cursor.isNull(_cursorIndexOfUuid)) {
              _tmp_1 = null;
            } else {
              _tmp_1 = _cursor.getString(_cursorIndexOfUuid);
            }
            _result.uuid = __tripTypeConverter.toUUID(_tmp_1);
            if (_cursor.isNull(_cursorIndexOfTitle)) {
              _result.title = null;
            } else {
              _result.title = _cursor.getString(_cursorIndexOfTitle);
            }
            if (_cursor.isNull(_cursorIndexOfDestination)) {
              _result.destination = null;
            } else {
              _result.destination = _cursor.getString(_cursorIndexOfDestination);
            }
            if (_cursor.isNull(_cursorIndexOfDate)) {
              _result.date = null;
            } else {
              _result.date = _cursor.getString(_cursorIndexOfDate);
            }
            if (_cursor.isNull(_cursorIndexOfDuration)) {
              _result.duration = null;
            } else {
              _result.duration = _cursor.getString(_cursorIndexOfDuration);
            }
          } else {
            _result = null;
          }
          return _result;
        } finally {
          _cursor.close();
        }
      }

      @Override
      protected void finalize() {
        _statement.release();
      }
    });
  }

  public static List<Class<?>> getRequiredConverters() {
    return Collections.emptyList();
  }
}

我被告知我需要使用 Executor 进行 INSERT、UPDATE 和 DELETE,这样它们就不会阻塞主线程,所以我不确定如何在不删除 executor 的情况下解决这个问题。

据我所知,没有实际的 Runnable 对象要返回,所以它不知道该怎么做?如果我说错了,请纠正我。

但是,是的,我只是不知道如何绕过需要 Runnable 返回类型的执行程序,但是没有 Runnable 可以返回。任何帮助将不胜感激

【问题讨论】:

标签: java android android-room


【解决方案1】:

您正试图告诉 room 从 insert 返回一个 Runnable。 Room 知道 @Insert 只能返回 voidLong/long (插入行的 rowid)。

  • 如果 @Insert 插入多行,则它可以返回 void、long[] 或 Long[]。
  • 如果您查看构建日志,那么

你不能拥有:-

@Insert
Runnable insertTrip(Trip trip);

它必须是以下之一:-

@Insert
void insertTrip(Trip trip);

@Insert
long insertTrip(Trip trip);

@Insert
Long insertTrip(Trip trip);

@Update 和 @Delete 类似,但它们返回 int(数量或受影响的行数)

要获取/使用 Runnable,您可以使用:-

void insertTrip(Trip trip){
    executor.execute(new Runnable() {
        @Override
        public void run() {
            tripDao.insertTrip(trip);
        }
    });
}
  • 显然其他人也是如此。

工作示例

使用 (注意一个简单的 Trip 类,但所有其他类根据您的问题栏进行上述更改) :-

    TripRepository.initialise(this);
    Trip atrip = new Trip();
    atrip.tripName = "My Trip";
    TripRepository.get().insertTrip(atrip);

结果:-

【讨论】:

  • @Insert can only return void or Long/long (the rowid of the inserted row). 刚刚花了一个小时弄清楚我做错了什么。谢谢!
猜你喜欢
  • 2019-11-20
  • 1970-01-01
  • 2020-09-07
  • 2022-01-02
  • 2019-11-20
  • 2016-03-19
  • 2020-04-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多