Head First Android开发小总结-创建数据库和连接数据库

本文介绍了一个简单的Android应用程序遇到的问题及解决方法,并详细讲解了如何在Android应用中使用SQLite数据库,包括创建、升级数据库以及如何使用SQLiteDatabase进行数据操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

布局什么的先不说,昨天运行一个连接数据库的项目,手机上运行起来,每当点击一个复选框的时候,程序就会崩溃。

idea没有报出错误,我自己检查代码是看不出什么的,加断点调式。

加断点,点那个虫子

然后左下角点开Debug查看状态,运行程序,f8下一步,也可以在Android Monitor看到是values是null,定位到出错的地方。

点击下一步时候,没反应了,我使用了AsyncTask异步任务操作,总是自己中断调式。

然而搜搜并没有说异步调式怎么办。以后能学到再说。

不过这个小程序总算知道问题出在哪里了。还是异步任务那里。我在一个方法里面创建了一个对象,在第一个需要调用的子方法里面为它赋值,下一个子方法使用它。这里显示它是空的,所以程序运行时候崩溃。

原因竟然是我在第一个子方法立赋值时候重新定义了一遍。

导致全局的那个对象是被第二个子方法使用时候显示空值。

emmmmm

注意到一点就是如果在子方法里使用对象时候不要和全局对象重名。

还有俺们宇哥说的java编写规范,让我写“ = ”的时候两边加空格。好的。


接下来总结一下Android 数据库的小知识。

(一)这是创建数据库

1. SQLite 是一种文件数据库,使用代码可以完成数据库的操作功能。利用SQLiteDatabase类访问SQLite数据库。

2.  可以使用SQLite帮助器来创建和管理数据库。创建SQLite帮助器要扩展SQLiteOpenelper类。

3.  第一次使用数据库会执行Oncreate()方法创建一个数据库,使用SQLiteDatabase execSQL(String)方法执行SQL命令。数据库升级要调用onUpgrade()方法,所以这俩方法是必须的。

4.  数据库升级是通过查看版本号完成的,为了完成数据库的升级,把方法写出来在进行调用。

那个小列子创建数据库代码如下

class StarbuzzDatabaseHelper extends SQLiteOpenHelper{
    private static final String DB_NAME="starbuzz";
    private static final int DB_VERSION=2;//SQLite帮助器检查版本号

    StarbuzzDatabaseHelper(Context context){
        super(context,DB_NAME,null,DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db){

       /* db.execSQL("CREATE TABLE DRINK("
                +"_id INTEGER PRIMARY KEY AUTOINCREMENT,"
                +"NAME TEXT,"
                +"DESCRIPTION TEXT,"
                +"IMAGE_RESOURCE_ID INTEGER);");

        insertDrink(db,"Latte","Espresso with milk",R.drawable.latte);
        insertDrink(db,"Cappuccino","Espresso hot milk",R.drawable.cappuccino);
        insertDrink(db,"Filter","our best drip coffee",R.drawable.filter);*/

        updataMyDatabase(db,0,DB_VERSION);
    }



    @Override
    public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion){

        updataMyDatabase(db,oldVersion,newVersion);

    }

    //做一个数据库升级方法
    private void updataMyDatabase(SQLiteDatabase db,int oldVersion,int newVersion){
        if(oldVersion<1){
            db.execSQL("CREATE TABLE DRINK("
                    +"_id INTEGER PRIMARY KEY AUTOINCREMENT,"
                    +"NAME TEXT,"
                    +"DESCRIPTION TEXT,"
                    +"IMAGE_RESOURCE_ID INTEGER);");

            insertDrink(db,"Latte","Espresso with milk",R.drawable.latte);
            insertDrink(db,"Cappuccino","Espresso hot milk",R.drawable.cappuccino);
            insertDrink(db,"Filter","our best drip coffee",R.drawable.filter);
        }
        if(oldVersion<2){
            db.execSQL("ALTER TABLE DRINK ADD COLUMN FAVORITE NUMERIC");
        }
    }


    //一个和插入的方法
    private static void insertDrink(SQLiteDatabase db,String name,String description,int resourceId){
        ContentValues drinkValues=new ContentValues();
        drinkValues.put("NAME",name);
        drinkValues.put("DESCRIPTION",description);
        drinkValues.put("IMAGE_RESOURCE_ID",resourceId);
        db.insert("DRINK",null,drinkValues);
    }
}

(二)是连接数据库,抄一下小总结

1.  使用SQLiteDatabase query()创建游标,在底层,这回建立一个SQL SELECT 语句。然后利用这个游标来读写数据库。

2.  getWritableDatabase()和getReadableDatabase()返回数据库对象,从写法可以看出来,前者支持读写,后者是只读,但后者是有有可能允许读写的,在不被允许的情况下才是只读功能。这个小程序使用前者容易造出数据库的不可访问引发程序bedug。

3.  获得数据库访问权限,取得数据当然是要利用起来的,不然干吗连接它,这里假设要取得数据并在listView显示,做法就是用一个使用游标的适配器CursorAdapter,实例化SimpleCursorAdapter用游标返回的值填充listView。

为真不懂得布局,不管了在这里放段代码吧。

public class DrinkCategoryActivity extends ListActivity {

    //增加这些私有变量,以便关闭
    private SQLiteDatabase db;
    private Cursor cursor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       // setContentView(R.layout.activity_drink_category);
        ListView listDrinks=getListView();

        /*不再使用drink类的数组适配器填充,而选择使用游标 适配器
        //用drinks数组填充列表试图
        ArrayAdapter<Drink> listAdapter=new ArrayAdapter<Drink>(this,
                android.R.layout.simple_list_item_1,
                Drink.drinks);
        listDrinks.setAdapter(listAdapter);*/

        //使用游标获取饮品数据,在listView填充饮品列表
        try{
            //得到数据库的引用
            SQLiteOpenHelper starbuzzDatabaseHelper =new StarbuzzDatabaseHelper(this);
            //从数据库读取数据
            db=starbuzzDatabaseHelper.getReadableDatabase();
            //游标必须包含_id列,
            cursor=db.query("DRINK",
                    new String[]{"_id","NAME"},
                    null,null,null,null,null);
            //创建一个游标适配器,显示name列内容
            CursorAdapter listAdapter=new SimpleCursorAdapter(this,
                    android.R.layout.simple_list_item_1,
                    cursor,
                    new String[]{"NAME"},
                    new int[]{android.R.id.text1},
                    0);
            //使用这个游标适配器
            listDrinks.setAdapter(listAdapter);
        }catch (SQLException e){
            Toast toast =Toast.makeText(this,"Database unavailable",Toast.LENGTH_SHORT);
            toast.show();
        }
    }

    //在这个方法中关闭游标和数据库,游标会一直保持打开,知道适配器不再需要为止
    @Override
    public void onDestroy(){
        super.onDestroy();
        cursor.close();
        db.close();
    }

    @Override
    public void onListItemClick(ListView listView, View view,int position,long id){
        Intent intent=new Intent(DrinkCategoryActivity.this,DrinkActivity.class);
        intent.putExtra(DrinkActivity.EXTRA_DRINKNO,(int) id);
        startActivity(intent);
    }
}

ohno。。怎么这么乱。

4.  比如主界面有个更新,那么返回界面时候就希望看到有更新,但是游标只在创建时候获取数据,要使用changeCursor()把游标适配器替换为提供一个新目标,在返回时候活动中再取数据。然后关闭原来的游标。

5.  记得最后游标和数据库都要关闭。

一些抄来的代码如下

public class TopLevelActivity extends AppCompatActivity {

    //创建私有变量以便关闭在onDstory
    private SQLiteDatabase db;
    private Cursor favoriteCursor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_top_level);
        //床卷一个监听
        AdapterView.OnItemClickListener itemClickListener = new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> listView, View v, int position, long id) {
                if (position == 0) {
                    Intent intent = new Intent(TopLevelActivity.this, DrinkCategoryActivity.class);
                    startActivity(intent);
                }
            }
        };
        //关联到listView
        ListView listView = (ListView) findViewById(R.id.list_options);
        listView.setOnItemClickListener(itemClickListener);


        //得到favorite列表视图
        ListView listFavorites = (ListView) findViewById(R.id.list_favorites);
        try {
            SQLiteOpenHelper starbuzzDatabaseHelper = new StarbuzzDatabaseHelper(this);
            db = starbuzzDatabaseHelper.getReadableDatabase();
            favoriteCursor = db.query("DRINK",
                    new String[]{"_id", "NAME" },
                    "FAVORITE=1",
                    null, null, null, null);
            //在游标适配器中使用游标,显示name列
            CursorAdapter favoriteAdapter = new SimpleCursorAdapter(TopLevelActivity.this,
                    android.R.layout.simple_list_item_1,
                    favoriteCursor,
                    new String[]{"NAME" },
                    new int[]{android.R.id.text1},
                    0);
            //使用这个游标适配器
            listFavorites.setAdapter(favoriteAdapter);
        } catch (SQLiteException e) {
            Toast toast = Toast.makeText(this, "Database unavailable", Toast.LENGTH_SHORT);
            toast.show(); }

            //如果点击列表视图就调用此方法
            listFavorites.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                //单击favorite list 中的一项,常见一个意图,启动DrinkActivity并传入这个饮品的id
                public void onItemClick(AdapterView<?> ListView, View v, int position, long id) {
                    Intent intent = new Intent(TopLevelActivity.this, DrinkActivity.class);
                    intent.putExtra(DrinkActivity.EXTRA_DRINKNO, (int) id);
                    startActivity(intent);
                }
            });
    }
    @Override
    public void onDestroy () {
        super.onDestroy();
        favoriteCursor.close();
        db.close();
    }

    //怎么刷新数据游标
    public void onRestart(){
        super.onRestart();
        try {
            StarbuzzDatabaseHelper starbuzzDatabaseHelper=new StarbuzzDatabaseHelper(this);
            db=starbuzzDatabaseHelper.getReadableDatabase();
            Cursor newCursor=db.query("DRINK",
                    new String[]{"_id","NAME"},
                    "FAVORITE=1",
                    null,null,null,null);
            ListView listFavorite=(ListView)findViewById(R.id.list_favorites);
            CursorAdapter adapter=(CursorAdapter) listFavorite.getAdapter();
            //将游标适配器 当前多使用的游标 替换为新游标
            adapter.changeCursor(newCursor);
            favoriteCursor=newCursor;
        }catch (SQLiteException e) {
            Toast toast = Toast.makeText(this, "Database unavaiable", Toast.LENGTH_SHORT);
            toast.show(); }
    }
}

什么什么阿 日常加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值