数据库未从 Activity 恢复

Posted

技术标签:

【中文标题】数据库未从 Activity 恢复【英文标题】:Database not restored from Activity 【发布时间】:2018-04-10 08:15:57 【问题描述】:

我在 android 中遇到了数据库问题。 我想从一个活动中收集数据,然后将它们传输到另一个应该将它们显示到 ListView 中并将它们保存到数据库中的活动。 问题是应用程序只显示列表视图中的第一项,我不知道是否所有数据都保存到数据库中。 当我尝试插入新项目时,应用程序可能会覆盖第一个项目并显示最新的项目。 非常感谢!

public class HomeActivity extends AppCompatActivity 

Button addPets;

private ListView mainListView;

private ArrayList<User> listUser;
private ArrayAdapter adapter;
private DBAdapter dbAdapter;

DBOpenHelper myDb;


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



    addPets = (Button)findViewById(R.id.add_friends);
    addPets.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            Intent apriRegistraPet = new Intent(HomeActivity.this, RegisterActivity.class);
            startActivity(apriRegistraPet);
        
    );

    dbAdapter = DBAdapter.getInstance(this);

    mainListView = (ListView)findViewById(R.id.elenco_pets);

    listUser = new ArrayList<User>();
    adapter = new ArrayAdapter<User>(this, android.R.layout.simple_list_item_1, listUser);

    mainListView.setAdapter(adapter);
    mainListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() 
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) 
            onLongClick(position, mainListView);
            return true;
        
    );





private void addNewItem(User user) 

    long idx = dbAdapter.insertUser(user);
    user.setId(idx);

    listUser.add(0, user);
    adapter.notifyDataSetChanged();




private void onLongClick(final int position, final ListView listView)
    User user = (User)listView.getItemAtPosition(position);
    Toast.makeText(getApplicationContext(), "Deleted Item", Toast.LENGTH_LONG).show();

    if(!dbAdapter.deleteUser(user))
        return;
    

    listUser.remove(user);
    adapter.notifyDataSetChanged();


@Override
protected void onResume() 

    super.onResume();
    dbAdapter.open();
    fillData();


    Bundle extras = getIntent().getExtras();
    if(extras != null)
        String nome = extras.getString("Nome");
        String razza = extras.getString("Razza");
        String sesso = extras.getString("Sesso");
        User user = new User(0, nome, razza, sesso, 10, 2000);
        addNewItem(user);

    




public void fillData()
    Cursor cursor = dbAdapter.getAllEntries();
    this.listUser.clear();

    cursor.moveToFirst();
    while(!cursor.isAfterLast())

        long idx = cursor.getLong(cursor.getColumnIndex(DBContract.AttributiRegistrazione._ID));
        String nome = cursor.getString(cursor.getColumnIndex(DBContract.AttributiRegistrazione.NOME));
        String razza = cursor.getString(cursor.getColumnIndex(DBContract.AttributiRegistrazione.RAZZA));
        String sesso = cursor.getString(cursor.getColumnIndex(DBContract.AttributiRegistrazione.SESSO));
        this.listUser.add(0, new User(idx, nome, razza, sesso, 10, 2000));
        cursor.moveToNext();

    

    cursor.close();
    adapter.notifyDataSetChanged();

这是注册活动

public class RegisterActivity extends AppCompatActivity 

ImageButton settaImmagine;
String imgDecodableString;

Spinner sprazza;
Spinner spsesso;

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

    //Clicco V e mette nella listview
    ImageButton salva = (ImageButton)findViewById(R.id.button_salva);
    salva.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 

            final EditText editText = (EditText)findViewById(R.id.name);
            sprazza = (Spinner)findViewById(R.id.spinner_razza);
            String razza = sprazza.getSelectedItem().toString();
            spsesso = (Spinner)findViewById(R.id.spinner_sesso);
            String sesso = spsesso.getSelectedItem().toString();

            Intent resultIntent = new Intent(RegisterActivity.this, HomeActivity.class);
            resultIntent.putExtra("Nome", editText.getText().toString());
            resultIntent.putExtra("Razza", razza);
            resultIntent.putExtra("Sesso", sesso);

            startActivity(resultIntent);
        
    );

DBAdapter 类;

public class DBAdapter 

private static final String TAG = "DBAdapter";
private static DBAdapter dbAdapter;
private static DBOpenHelper dbOpenHelper;
private SQLiteDatabase db;

public synchronized static DBAdapter getInstance(Context context)

    if(dbAdapter==null) 
        dbAdapter = new DBAdapter(context.getApplicationContext());
    
    return dbAdapter;



private DBAdapter(Context context) dbOpenHelper = DBOpenHelper.getInstance(context);

public DBAdapter open() throws SQLException
    try
        db = dbOpenHelper.getWritableDatabase();
    
    catch (SQLException e)
        Log.e(TAG, e.toString());
        throw e;
    
    return this;


public void close() 
    db.close();



public long insertUser (User user)

    Log.v(TAG, "Inserisci un User to DB: " +user.getNome());
    long idx = db.insert(DBContract.AttributiRegistrazione.NOME_TABELLA, null, user.getAsContentValue());
    user.setId(idx);
    Log.v(TAG, "Added user with ID: "+idx);
    return idx;



public boolean deleteUser (User user)

    Log.v(TAG, "Removing User: " + user.getClass());
    return db.delete(DBContract.AttributiRegistrazione.NOME_TABELLA,
            DBContract.AttributiRegistrazione.NOME + "=" + user.getNome(), null) == 1;


public boolean deleteUser(String name)
    Log.v(TAG, "Removing user: " + name);
    return db.delete(DBContract.AttributiRegistrazione.NOME_TABELLA,
            DBContract.AttributiRegistrazione.NOME + "=" + name, null) == 1;


public Cursor getAllEntries()
    return db.query(DBContract.AttributiRegistrazione.NOME_TABELLA,
            null, null, null, null, null, null);

错误日志

E/SQLiteLog: (1) table Registrazione has no column named Anno_nascita 04-10 13:57:21.142 10175-10175/com.b.uzzo.snappaw E/SQLiteDatabase: Error inserting Anno_nascita=2000 Peso=10.0 Nome=simone Sesso=Maschio Razza=Akita Inu
android.database.sqlite.SQLiteException: table Registrazione has no column named Anno_nascita (code 1): , while compiling: INSERT INTO Registrazione(Anno_nascita,Peso,Nome,Sesso,Razza) VALUES (?,?,?,?,?)
    at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
    at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:898)
    at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:509)
    at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
    at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
    at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1500)
    at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1373)
    at com.b.uzzo.snappaw.DBAdapter.insertUser(DBAdapter.java:49)
    at com.b.uzzo.snappaw.HomeActivity.addNewItem(HomeActivity.java:105)
    at com.b.uzzo.snappaw.HomeActivity.onResume(HomeActivity.java:140)
    at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1269)
    at android.app.Activity.performResume(Activity.java:6770)
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3522)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3591)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2825)
    at android.app.ActivityThread.-wrap12(ActivityThread.java)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1542)
    at android.os.Handler.dispatchMessage(Handler.java:110)
    at android.os.Looper.loop(Looper.java:203)
    at android.app.ActivityThread.main(ActivityThread.java:6319)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1085)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:946)

但它是在 DBContract 类中创建的

public class DBContract 

static final String DB_NAME = "RegistrazioneCuccioli";
static final int DB_VERSION = 1;

static abstract class AttributiRegistrazione implements BaseColumns

    static final String NOME_TABELLA = "Registrazione";
    static final String NOME = "Nome";
    static final String RAZZA = "Razza";
    static final String SESSO = "Sesso";
    static final String PESO = "Peso";
    static final String ANNO_NASCITA = "Anno_nascita";


【问题讨论】:

你能描述一下dbAdapter.insertUser(user);吗? '该应用仅显示列表视图中的第一项' - 您是否尝试向上滚动?我问这个是因为我以前发生过很多次。 该方法应将“用户”插入数据库。无论如何,我发布了课程 【参考方案1】:

在 HomeActivity 类的 fillData 方法中,您正在使用 list.add(0,new User()) 将数据添加到 Arraylist,添加您的数据进入 0 索引,这就是你的问题的原因。您应该调用 list.add(user)

试试这个更新的代码:

public void fillData()
 Cursor cursor = dbAdapter.getAllEntries();
 this.listUser.clear();

 if (cursor.moveToFirst())
  do 
    long idx = cursor.getLong(cursor.getColumnIndex(DBContract.AttributiRegistrazione._ID));
    String nome = cursor.getString(cursor.getColumnIndex(DBContract.AttributiRegistrazione.NOME));
    String razza = cursor.getString(cursor.getColumnIndex(DBContract.AttributiRegistrazione.RAZZA));
    String sesso = cursor.getString(cursor.getColumnIndex(DBContract.AttributiRegistrazione.SESSO));
    User user = new User(idx, nome, razza, sesso, 10, 2000);
    this.listUser.add(user);
    while(cursor.moveToNext());



cursor.close();
adapter.notifyDataSetChanged();

【讨论】:

试试this solution to retrieve data from cursor 感谢您的帮助,但更新后的代码出现了与我相同的问题 你调试过你的代码吗?用户的 Arraylist 的大小是多少? 你在 HomeActivity 类的 addNewItem 方法中做同样的事情。请改正 我不明白“在 addNewItem 方法中做同样的事情”是什么意思

以上是关于数据库未从 Activity 恢复的主要内容,如果未能解决你的问题,请参考以下文章

Android处理运行时变更保存数据状态恢复Activity

转android笔记--保存和恢复activity的状态数据

android笔记--保存和恢复activity的状态数据

activity状态保存与恢复

Android中突发情况Activity数据的保存和恢复

Android——Activity恢复用户用EditText输入的数据