java - 无法编辑或更新 Room 数据库条目

标签 java android android-intent mvvm android-room

我正在构建一个应用程序,用户可以在其中存储他/她的用户名和密码。该应用程序有一个简单的用户界面。主线程在操作栏上有一个条目列表、一个 FAB 和一个删除所有图标。我的问题是我无法编辑和更新现有条目。

我的 MainActivity.javaonCreate() 中有以下代码。当用户按住某个条目时,它会启动 AddEditEntry.java Activity 。这里发生的情况是,启动的 Activity 在其 EditText 字段中没有现有的条目数据:

adapter.setOnItemLongClickListener(new RecyclerViewAdapter.OnItemLongClickListener() {
            @Override
            public void onItemLongClick(Entries entries) {
                Intent intent = new Intent(MainActivity.this, AddEditEntry.class);
                intent.putExtra(AddEditEntry.EXTRA_USERNAME, entry.getUsername());
                intent.putExtra(AddEditEntry.EXTRA_HINT, entry.getHint());
                intent.putExtra(AddEditEntry.EXTRA_PASSWORD, entry.getPassword());
                intent.putExtra(AddEditEntry.EXTRA_ID, entry.getId());
                startActivityForResult(intent, EDIT_ENTRY_REQUEST);
            }
        });

在我的 AddEditEntry.java Activity 中,保存按钮的 onClick 中有以下代码。我将新数据作为附加内容添加到 Intent 中:

saveEntry.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent data = new Intent();
                data.putExtra(EXTRA_USERNAME, usernameEditText.getText().toString());
                data.putExtra(EXTRA_HINT, hintEditText.getText().toString());
                data.putExtra(EXTRA_PASSWORD, passwordEditText.getText().toString());

                int id = getIntent().getIntExtra(EXTRA_ID, -1);

                if(id != -1){data.putExtra(EXTRA_ID, id);}

                setResult(RESULT_OK, data);
                finish();
            }
        });

回到我的MainActivity.jav,这是我的onActivityResult():

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if(requestCode == ADD_ENTRY_REQUEST && resultCode == RESULT_OK){
        String username = Objects.requireNonNull(data).getStringExtra(AddEditEntry.EXTRA_USERNAME);
        String password = Objects.requireNonNull(data).getStringExtra(AddEditEntry.EXTRA_PASSWORD);
        String hint = Objects.requireNonNull(data).getStringExtra(AddEditEntry.EXTRA_HINT);

        Entries entry = new Entries(username, hint, password);
        viewModel.insert(entry);

        Toast.makeText(this, "Entry added!", Toast.LENGTH_SHORT).show();

    }else if(requestCode == EDIT_ENTRY_REQUEST && resultCode == RESULT_OK){
        int id = Objects.requireNonNull(data).getIntExtra(AddEditEntry.EXTRA_ID, -1);
        String username = Objects.requireNonNull(data).getStringExtra(AddEditEntry.EXTRA_USERNAME);
        String password = Objects.requireNonNull(data).getStringExtra(AddEditEntry.EXTRA_PASSWORD);
        String hint = Objects.requireNonNull(data).getStringExtra(AddEditEntry.EXTRA_HINT);

        if (id == -1){Toast.makeText(addEditEntry, "Something went wrong", Toast.LENGTH_SHORT).show();}

        Entries entry = new Entries(username, hint, password);
        entry.setId(id);
        viewModel.update(entry);

        Toast.makeText(this, "Entry updated", Toast.LENGTH_SHORT).show();

    }
    else{Toast.makeText(this, "Entry not added!", Toast.LENGTH_SHORT).show();}
}

当我运行应用程序并尝试编辑条目时,Toast 消息显示“条目已更新!”所以它确实运行了该代码,但更改不存在。我尝试停止该应用程序并重新启动它以刷新它,但它仍然不存在。

ViewModel.java:

public class EntryViewModel extends AndroidViewModel {
    private EntryRepository repository;
    private LiveData<List<Entries>> allEntries;


    public EntryViewModel(@NonNull Application application) {
        super(application);
        repository = new EntryRepository(application);
        allEntries = repository.getAllEntries();
    }

    public void insert(Entries entries){repository.insert(entries);}

    public void update(Entries entries){repository.update(entries);}

    public void delete(Entries entries){repository.delete(entries);}

    public void deleteAll(){repository.deleteAllEntries();}

    public LiveData<List<Entries>> getAllEntries() {return allEntries;}
}

EntryRepository.java:

public class EntryRepository {
    private EntryDAO entryDAO;
    private LiveData<List<Entries>> allEntries;

    public EntryRepository(Application application){
        EntryDatabase database = EntryDatabase.getInstance(application);
        entryDAO = database.generateDao();
        allEntries = entryDAO.getAllEntries();
    }

    public void insert(Entries entries){new InsertEntryAsyncTask(entryDAO).execute(entries);}

    public void update(Entries entries){new UpdateEntryAsyncTask(entryDAO).execute(entries);}

    public void delete(Entries entries){new DeleteEntryAsyncTask(entryDAO).execute(entries);}

    public void deleteAllEntries(){new DeleteAllEntriesAsyncTask(entryDAO).execute();}

    public LiveData<List<Entries>> getAllEntries(){return allEntries;}


    public static class InsertEntryAsyncTask extends AsyncTask<Entries, Void, Void>{
        private EntryDAO entryDAO;

        private InsertEntryAsyncTask(EntryDAO entryDAO){this.entryDAO = entryDAO;}

        @Override
        protected Void doInBackground(Entries... entries) {
            entryDAO.insert(entries[0]);
            return null;
        }
    }

    public static class UpdateEntryAsyncTask extends AsyncTask<Entries, Void, Void>{
        private EntryDAO entryDAO;

        private UpdateEntryAsyncTask(EntryDAO entryDAO){
            this.entryDAO = entryDAO;
        }
        @Override
        protected Void doInBackground(Entries... entries) {
            entryDAO.update(entries[0]);
            return null;
        }
    }

    public static class DeleteEntryAsyncTask extends AsyncTask<Entries, Void, Void>{
        private EntryDAO entryDAO;

        private DeleteEntryAsyncTask(EntryDAO entryDAO){this.entryDAO = entryDAO;}

        @Override
        protected Void doInBackground(Entries... entries) {
            entryDAO.delete(entries[0]);
            return null;
        }
    }

    public static class DeleteAllEntriesAsyncTask extends AsyncTask<Void, Void, Void>{
        private EntryDAO entryDAO;

        private DeleteAllEntriesAsyncTask(EntryDAO entryDAO){this.entryDAO = entryDAO;}

        @Override
        protected Void doInBackground(Void... voids) {
            entryDAO.deleteAllEntries();
            return null;
        }
    }
}

EntryDAO.java:

@Dao
public interface EntryDAO {

    @Insert
    void insert(Entries entries);

    @Update
    void update(Entries entries);

    @Delete
    void delete(Entries entries);

    @Query("DELETE FROM entries_table")
    void deleteAllEntries();

    @Query("SELECT * FROM entries_table")
    LiveData<List<Entries>> getAllEntries();
}

Entry.java:

@Entity(tableName = "entries_table")
public class Entries {
    @PrimaryKey(autoGenerate = true)
    private int id;

    private String username, hint, password;

    public Entries(String username, String hint, String password){
        this.username = username;
        this.hint = hint;
        this.password = password;
    }

    public Entries(){}

    public int getId() {return id;}

    public void setId(int id) {this.id = id;}

    public String getUsername() {return username;}

    public void setUsername(String username) {this.username = username;}

    public String getHint() {return hint;}

    public void setHint(String hint) {this.hint = hint;}

    public String getPassword() {return password;}

    public void setPassword(String password) {this.password = password;}
}

这是我的 AddEditEntry.java 类的 onCreate() 。我添加了以下 Toast 消息来查看它是否正在接收数据,结果却没有。 Toast 消息为空:

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

        usernameEditText = findViewById(R.id.username_field);
        passwordEditText = findViewById(R.id.password_field);
        hintEditText = findViewById(R.id.hint_field);

        passwordABCD = findViewById(R.id.upp_checkbox);
        passwordabcd = findViewById(R.id.low_checkbox);
        password0123 = findViewById(R.id.num_checkbox);
        passwordSymbols = findViewById(R.id.sym_checkbox);

        radio4 = findViewById(R.id.four);
        radio8 = findViewById(R.id.eight);
        radio12 = findViewById(R.id.twelve);
        radio16 = findViewById(R.id.sixteen);

        Button generatePassword = findViewById(R.id.btn_password_generate);
        Button saveEntry = findViewById(R.id.btn_save);

        Intent intent = getIntent();

        if(intent.hasExtra(EXTRA_ID)){
        setTitle("Edit Entry");
        usernameEditText.setText(Objects.requireNonNull(getIntent().getExtras()).getString(EXTRA_USERNAME));
        passwordEditText.setText(Objects.requireNonNull(getIntent().getExtras()).getString(EXTRA_PASSWORD));
        hintEditText.setText(Objects.requireNonNull(getIntent().getExtras()).getString(EXTRA_HINT));

        Toast.makeText(this, "Info Received!!!", Toast.LENGTH_SHORT).show();
        Toast.makeText(this, Objects.requireNonNull(getIntent().getExtras()).getString(EXTRA_USERNAME), Toast.LENGTH_SHORT).show();
        Toast.makeText(this, Objects.requireNonNull(getIntent().getExtras()).getString(EXTRA_PASSWORD), Toast.LENGTH_SHORT).show();
        Toast.makeText(this, Objects.requireNonNull(getIntent().getExtras()).getString(EXTRA_HINT), Toast.LENGTH_SHORT).show();
    }
        else{setTitle("Add Entry");}

        generatePassword.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {passwordEditText.setText(generatedPassword());}});

        saveEntry.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent data = new Intent();
                data.putExtra(EXTRA_USERNAME, usernameEditText.getText().toString());
                data.putExtra(EXTRA_HINT, hintEditText.getText().toString());
                data.putExtra(EXTRA_PASSWORD, passwordEditText.getText().toString());

                int id = getIntent().getIntExtra(EXTRA_ID, -1);

                if(id != -1){data.putExtra(EXTRA_ID, id);}

                setResult(RESULT_OK, data);
                finish();
            }
        });
    }

最佳答案

这样做

在您的MainActivity.java

    ....
    ....
    adapter.setOnItemLongClickListener(new RecyclerViewAdapter.OnItemLongClickListener() {
        @Override
        public void onItemLongClick(Entries entries) {
            entry = entries;  // this is very important, entry holds the current edited item
            Intent intent = new Intent(MainActivity.this, AddEditEntry.class);
            intent.putExtra(AddEditEntry.EXTRA_USERNAME, entry.getUsername());
            intent.putExtra(AddEditEntry.EXTRA_HINT, entry.getHint());
            intent.putExtra(AddEditEntry.EXTRA_PASSWORD, entry.getPassword());
            // no need to pass the id, it's a autogenerated field 
            // intent.putExtra(AddEditEntry.EXTRA_ID, entry.getId());
            startActivityForResult(intent, EDIT_ENTRY_REQUEST);
        }
    });

    ....
    ...

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {

        if(requestCode == ADD_ENTRY_REQUEST && resultCode == RESULT_OK){
            ...
            ... 
        } else if(requestCode == EDIT_ENTRY_REQUEST && resultCode == RESULT_OK) {
            // in an Edit operation, id should not be modified, so, no need to pass this parameter 
            // int id = 
            // Objects.requireNonNull(data).getIntExtra(AddEditEntry.EXTRA_ID, -1);
            String username = Objects.requireNonNull(data).getStringExtra(AddEditEntry.EXTRA_USERNAME);
            String password = Objects.requireNonNull(data).getStringExtra(AddEditEntry.EXTRA_PASSWORD);
            String hint = Objects.requireNonNull(data).getStringExtra(AddEditEntry.EXTRA_HINT);

            // entry already exists, so, no need to create a new one            
            //Entries entry = new Entries(username, hint, password);
            //entry.setId(id);
            entry.setUsername(username);
            entry.setPassword(password);
            entry.setHint(hint);
            viewModel.update(entry);

            Toast.makeText(this, "Entry updated", Toast.LENGTH_SHORT).show();

        } else {
            Toast.makeText(this, "Entry not added!", Toast.LENGTH_SHORT).show();
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

其他备注...

在您的RecyclerViewAdapter.java

    // This is not needed. Your list is already created in your Room query
    //private List<Entries> entries = new ArrayList<>();

    private List<Entries> entries;

在您的MainActivity.java

    // This is not needed
    // AddEditEntry addEditEntry;
    ....
    ....
    // addEditEntry = new AddEditEntry();

关于java - 无法编辑或更新 Room 数据库条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56070803/

相关文章:

java - 如何将图像添加到 JFrame 项目

android - 在缺口设备模拟器上测试应用程序

android - 如何检查特定应用程序是否具有管理员权限,并转到其管理屏幕?

java - 如果不先滚动,则不会显示 RecyclerView 项目中的图像

java - setOnClickListener 方法中的重复代码 - android - java

android - 仅当 Activity 在后台时才将其带到前台的通知

java - 通过 Java Android 撰写电子邮件 - 尝试定位设备管理客户端

Java , System.exit() ?我该如何使用它?

java - Tomcat 中的同步和异步请求处理有何不同?

java - gson 和 json 反序列化