设为首页 收藏本站
查看: 948|回复: 0

[经验分享] Android (SQLite 数据库与ContentProvider)

[复制链接]
发表于 2016-11-30 10:06:52 | 显示全部楼层 |阅读模式
在Android中,对于数据的存贮,有几种方式,有文件方式,有文件式数据库方式,Android自带了一个SQLite数据库,做嵌入开发的人对这个跨平台的本地文件数据库一定不会陌生,在Android对于数据的访问,提出了新的方式,ContentProvider方式,类似于MS的ContentProvider方式的,OLEDB,及ODBC统一的数据方式。
我们首先来看看SQLite在 Android中的使用,在Android中有最简单的使用方式,就是利Context对象的openorCreateDatabase
我们来看看一段代码:

package test.DB;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class DBActivity extends Activity {
private SQLiteDatabase mdb = null;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initDatabase();
        setContentView(R.layout.main);        
    }
    @Override
public boolean onCreateOptionsMenu(Menu menu) {
  // TODO Auto-generated method stub
  super.onCreateOptionsMenu(menu);   
  menu.add(1, Menu.FIRST +1, 1, "GetName");  
  menu.add(1, Menu.FIRST +2, 2, "Test");   
  return true;  
}
   
    public boolean onOptionsItemSelected(MenuItem item) {
  // TODO Auto-generated method stub
  super.onOptionsItemSelected(item);
  switch (item.getItemId())
  {
   case Menu.FIRST+ 1:
   {
    TextView tv = (TextView)this.findViewById(R.id.view_main);
    tv.setText(this.getName());
    break;
   }
   case Menu.FIRST + 2:
   {
    this.setTitle("Del Item...");
    break;
   }   
  }
  return true;
}
   
    private void initDatabase()
    {
     mdb = this.openOrCreateDatabase("dbfile", 0, null);
     String sql_create = "create table test (id int, name TEXT)";
     mdb.execSQL(sql_create);
     String sql_insert = "insert into test(id, name) values(3, 'name3')";
     mdb.execSQL(sql_insert);
    }
    private String getName()
    {
     String name = null;
     
     Cursor cur = mdb.rawQuery("select * from test", null);
     cur.moveToFirst();
     while (!cur.isLast())
     {
      name = name  + cur.getString(1)+ "\r\n";
      cur.moveToNext();
     }
     return name;
    }
}

我们再来看看单独使用SQLiteOpenHelper方式:
先由SQLiteOpenHelper继承一个数据库操作类,其中onCreate, onUpgrade必须重载并实现,


package test.DB;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper {
@Override
public void onCreate(SQLiteDatabase db) {
  // TODO Auto-generated method stub  
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  // TODO Auto-generated method stub  
}
public DatabaseHelper(Context ct,String dbName)
{
  super(ct,dbName,null,1);  
}
public boolean insert(String insert)
{
  this.getWritableDatabase().execSQL(insert);
  return true;
}
public boolean update(String update)
{
  this.getWritableDatabase().execSQL(update);
  return true;
}
public boolean delete(String del)
{
  this.getWritableDatabase().execSQL(del);
  return true;
}
public Cursor query(String query)
{
  Cursor cur = this.getReadableDatabase().rawQuery(query, null);
  return cur;
}
}

再创建一个使用者(消费者)


package test.DB;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class DBActivity extends Activity {
private SQLiteDatabase mdb = null;
private DatabaseHelper helper = null;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initDatabase();
        setContentView(R.layout.main);        
    }
    @Override
public boolean onCreateOptionsMenu(Menu menu) {
  // TODO Auto-generated method stub
  super.onCreateOptionsMenu(menu);   
  menu.add(1, Menu.FIRST +1, 1, "GetName");  
  menu.add(1, Menu.FIRST +2, 2, "Test");   
  return true;  
}
   
    public boolean onOptionsItemSelected(MenuItem item) {
  // TODO Auto-generated method stub
  super.onOptionsItemSelected(item);
  switch (item.getItemId())
  {
   case Menu.FIRST+ 1:
   {
    TextView tv = (TextView)this.findViewById(R.id.view_main);
    tv.setText(this.getName());
    break;
   }
   case Menu.FIRST + 2:
   {
    this.setTitle("Del Item...");
    break;
   }   
  }
  return true;
}
   
    private void initDatabase()
    {
     helper = new DatabaseHelper(this,"dbfile");
     //mdb = this.openOrCreateDatabase("dbfile", 0, null);
     //String sql_create = "create table test (id int, name TEXT)";
     //mdb.execSQL(sql_create);
     String sql_insert = "insert into test(id, name) values(55, 'namexx')";
     //mdb.execSQL(sql_insert);
     helper.insert(sql_insert);
    }
    private String getName()
    {
     String name = null;  
     //mdb = helper.getReadableDatabase();
     Cursor cur = helper.query("select * from test");
     cur.moveToFirst();
     do
     {
      name = name  + cur.getString(1)+ "\n";      
      
     } while(cur.moveToNext());      
     
     return name;
    }
}

这些代码读起来是不是有点Visual Basic的感觉?呵呵,所以,以后说不定.net,Android,java,blackberry,最终都成为一致的API,当然,这只是我们的期望,这样大家不必整天花这么多时间学这些无聊的接口了。

好了,该我们的ContentProvider出场了,与Service,BroadcastReceiver等组件一样,继承特定的Interface,在AndroidManifest.xml里声明这个ContentProvider,调用者就可以拿来使用了。
首先我们定义一个ContentProvider:


package test.DB;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.widget.Toast;

public class TestProvider extends ContentProvider {
    private DatabaseHelper mdbHelper = null;
    final static String TABLE_NAME = "test";
@Override
public int delete(Uri arg0, String arg1, String[] arg2) {
  mdbHelper.getWritableDatabase().delete(TABLE_NAME, arg1, arg2);
  return 0;
}

@Override
public String getType(Uri uri) {
  // TODO Auto-generated method stub
  return null;
}

@Override
public Uri insert(Uri uri, ContentValues values) {
  // TODO Auto-generated method stub
  mdbHelper.getWritableDatabase().insert(TABLE_NAME, "", values);
  return null;
}

@Override
public boolean onCreate() {
  // TODO Auto-generated method stub
  mdbHelper = new DatabaseHelper(this.getContext(), "dbfile");
  return true;
}

@Override
public Cursor query(Uri uri, String[] projection, String selection,
   String[] selectionArgs, String sortOrder) {
  Cursor cur = mdbHelper.getReadableDatabase().query(TABLE_NAME,projection,selection,null,null,null, null);
  Toast.makeText(this.getContext(), "test Cur!", Toast.LENGTH_SHORT);
  return cur;
}

@Override
public int update(Uri uri, ContentValues values, String selection,
   String[] selectionArgs) {
  mdbHelper.getWritableDatabase().update(TABLE_NAME, values, selection, null);
  return 0;
}

}


老规矩,AndroidManifest.xml来定义这个Provider
<provider android:label="test_provider" android:authorities="com.my.provider" android:name="TestProvider">
    </provider>
这里的android:authorities = "com.my.provider"是标识这个ContentProvider,调用者可以根据这个标识来找到它,
我们组合一个能找到它的Uri,
public class ProviderConst {
public static final Uri MY_TEST_URI = Uri.parse("content://com.my.provider/test");

}

content 指的是内容提供者ContentProvider。
//com.my.provider映射到我们已定义的那个ContentProvider标识
/test这个作为一个参数,传给ContentProvider,可以根据这个参数来决定操作目标,比如数据库中的哪张表,文件中的那一部分数据等。

我们来操作这个内容提供者:
private String getName()
    {
     String name = null;      
     Cursor cur = this.getContentResolver().query(ProviderConst.MY_TEST_URI,new String[]{"id","name"},null, null, null);
     if (cur == null)
      return null;
     cur.moveToFirst();
     do
     {
      name = name  + cur.getString(1)+ "\n";      
      
     } while(cur.moveToNext());      
     
     return name;
    }
我们也可以这样使用:
private String getName()
    {
     String name = null;      
     Cursor cur = this.managedQuery(ProviderConst.MY_TEST_URI,new String[]{"id","name"},null, null, null);
     if (cur == null)
      return null;
     cur.moveToFirst();
     do
     {
      name = name  + cur.getString(1)+ "\n";      
      
     } while(cur.moveToNext());      
     
     return name;
    }
  

简单的使用方法我们已了解,那么,我们来分析一下复杂的内容。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-307561-1-1.html 上篇帖子: Android 批量插入到Sqlite数据库 下篇帖子: Android 数据存储和IO——SQLite(三)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表