简单的数据库交互展示
来源:互联网 发布:java 请求分发算法 编辑:程序博客网 时间:2024/05/22 13:13
简单的数据库交互展示
无论什么应用程序,与数据库的交互都是必不可少的,android当然更不例外。轻量级 开源的sqlite几乎成为移动开发数据库的事实标准。android也提供了api方便我们进行数据库的创建以及增删改查等等操作。
同时图片也是我们android应用程序最常用的信息展示的形式,除了可以从网络上动态的加载图片资源,对于那些变化更新频率不大的资源来说,放在资源文件也未尝不是一种很好的解决方案。
android放置图片通常有三种位置:
- res/drawable 会被编译成二进制,同时会被编译有资源id
- res/raw 不会被编译成二进制,会有资源id,不能有嵌套文件夹
- asset 目录也是原生文件夹,不会被appt编译为二进制文件,可以嵌套文件夹进行分类
- File 保存在内置存储器的文件
这里用asset作为展示,项目的结构
1.Sqlite数据库的创建
package com.example.db;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;public class krystalDBHelper extends SQLiteOpenHelper { private static final String DB_NAME = "krystal.db"; private static int version = 5; public static String TABLE_NAME = "krystal"; /* * The Cursor must include a column named _id or this class will not work. * Cursor必须包含一个键名为_id的列 */ private static final String createSql = "create table krystal(_id integer primary key autoincrement,name varchar(20),age integer,image_Url varchar(255),type varchar(20) )"; public krystalDBHelper(Context context) { super(context, DB_NAME, null, version); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(createSql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); db.execSQL(createSql); }}
2.创建ContentProvider
package com.example.db;import android.content.ContentProvider;import android.content.ContentUris;import android.content.ContentValues;import android.content.UriMatcher;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteQueryBuilder;import android.net.Uri;import android.util.Log;public class KrystalContentProvider extends ContentProvider { private krystalDBHelper dbHelper; public final static Uri Content_URI = Uri .parse("content://com.example.db.KrystalContentProvider/krystal"); public final static String COLUMN_NAME="name"; public final static String COLUMN_IMAGEURL="image_Url"; // 单行操作 还是多行操作 private static final int SINGLE_ROW = 1; private static final int ALLROWS = 2; private static final UriMatcher URI_MATCHER = new UriMatcher( UriMatcher.NO_MATCH); static { // 匹配 // 单行操作 多行操作授权相同,主要是路径不同 URI_MATCHER.addURI("com.example.db.KrystalContentProvider", "krystal/#", SINGLE_ROW); URI_MATCHER.addURI("com.example.db.KrystalContentProvider", "krystal", ALLROWS); } @Override public boolean onCreate() { dbHelper = new krystalDBHelper(getContext()); return true; } @Override public int delete(Uri arg0, String arg1, String[] arg2) { // TODO Auto-generated method stub return 0; } @Override public String getType(Uri uri) { int flag = URI_MATCHER.match(uri); switch (flag) { case SINGLE_ROW: return "vnd.android.cursor.item/krystal"; case ALLROWS: return "vnd.android.cursor.dir/krystal"; default: break; } return null; } @Override public Uri insert(Uri uri, ContentValues values) { SQLiteDatabase db = dbHelper.getWritableDatabase(); Uri newUri = null; int flag = URI_MATCHER.match(uri); Log.i("nikan", "insert ......." + flag); // 插入的Uri不带id,id为自动增长 // 所以插入的Uri会匹配为ALLROWS,或者不需要匹配验证 switch (flag) { case ALLROWS: Log.i("nikan", "insert 0002 ......."); long id = db.insert("krystal", null, values); newUri = ContentUris.withAppendedId(uri, id); Log.i("nikan", newUri.toString()); return newUri; default: break; } return null; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteDatabase db = dbHelper.getReadableDatabase(); // SQLiteQueryBuilder is a helper class that creates the // proper SQL syntax for us. SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder(); // Set the table we're querying. qBuilder.setTables(dbHelper.TABLE_NAME); // If the query ends in a specific record number, we're // being asked for a specific record, so set the // WHERE clause in our query. if ((URI_MATCHER.match(uri)) == SINGLE_ROW) { qBuilder.appendWhere("id=" + ContentUris.parseId(uri)); } // Make the query. Cursor c = qBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder); // 通知所有觀察者 ,數據集以改變 c.setNotificationUri(getContext().getContentResolver(), uri); return c; } @Override public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) { // TODO Auto-generated method stub return 0; }}
3.实体类
package com.example.model;public class krystal { private int id; private String name; private int age; private String image_Url; private String type; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getImage_Url() { return image_Url; } public void setImage_Url(String image_Url) { this.image_Url = image_Url; }}
4.针对数据库层的单元测试
package com.example.test;import com.example.db.KrystalContentProvider;import com.example.db.krystalDBHelper;import android.content.ContentResolver;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;import android.test.AndroidTestCase;import android.util.Log;public class dbTest extends AndroidTestCase { public void TestCreate() { krystalDBHelper helper = new krystalDBHelper(getContext()); helper.getWritableDatabase(); } public void TestInsert() { ContentResolver contentResolver = getContext().getContentResolver(); for (int i = 4; i < 10; i++) { ContentValues values = new ContentValues(); values.put("name", "nikan" + i); values.put("type", "hot"); values.put("age", 15 + i); values.put("image_Url", "file:///android_asset/images/krystal00" + i + ".jpg"); Uri uri = KrystalContentProvider.Content_URI; Log.i("nikan", uri.toString() + " ------>"); contentResolver.insert(uri, values); } } public void TestQuery() { ContentResolver contentResolver = getContext().getContentResolver(); // 指定ID,單行查詢 /* * Uri uri=ContentUris.withAppendedId(PersonContentProvider.Content_URI, * 2); Cursor cursor= contentResolver.query(uri, null, null, null, * null); */ Cursor cursor = contentResolver.query( KrystalContentProvider.Content_URI, null, "type=?", new String[] { "cold" }, null); while (cursor.moveToNext()) { String name = cursor.getString(cursor .getColumnIndex(KrystalContentProvider.COLUMN_NAME)); String image_Url = cursor.getString(cursor .getColumnIndex(KrystalContentProvider.COLUMN_IMAGEURL)); Log.i("nikan", "<<<-----" + name + "------>>" + image_Url); } }}
5.设置SimpleCursorAdapter 进行数据展示
package com.example.searchkrystal;import java.io.IOException;import java.io.InputStream;import java.util.zip.Inflater;import com.example.db.KrystalContentProvider;import com.example.utils.LoadImage;import com.example.utils.LoadImage.LoadSuccessCallback;import com.squareup.picasso.Picasso;import android.app.Activity;import android.app.LoaderManager.LoaderCallbacks;import android.content.Context;import android.content.CursorLoader;import android.content.Loader;import android.database.Cursor;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.net.Uri;import android.os.Bundle;import android.text.TextUtils;import android.util.Log;import android.view.LayoutInflater;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.ImageView;import android.widget.ListView;import android.widget.SearchView;import android.widget.SearchView.OnCloseListener;import android.widget.SearchView.OnQueryTextListener;import android.widget.SimpleCursorAdapter;public class MainActivity extends Activity implements LoaderCallbacks<Cursor>, OnQueryTextListener, OnCloseListener { private ImageView imageView; private ListView listView; // This is the Adapter being used to display the list's data. SimpleCursorAdapter mAdapter; // The SearchView for doing filtering. SearchView mSearchView; // If non-null, this is the current filter the user has provided. String mCurFilter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /* * imageView = (ImageView) findViewById(R.id.imageView); * LoadImage.LoadImageFromAsset(this, "images/krystal007.jpg", new * LoadSuccessCallback() { * * @Override public void setImage(Bitmap bitmap) { * imageView.setImageBitmap(bitmap); * * } }); */ listView = (ListView) findViewById(R.id.listView1); Cursor cursor = getContentResolver().query( KrystalContentProvider.Content_URI, null, "type=?", new String[] { "hot" }, null); while (cursor.moveToNext()) { String name = cursor.getString(cursor .getColumnIndex(KrystalContentProvider.COLUMN_NAME)); String image_Url = cursor.getString(cursor .getColumnIndex(KrystalContentProvider.COLUMN_IMAGEURL)); Log.i("nikan", "<<<-----" + name + "------>>" + image_Url); } // Create an empty adapter we will use to display the loaded data. mAdapter = new SimpleCursorAdapter(this, R.layout.list_item, cursor, new String[] { KrystalContentProvider.COLUMN_IMAGEURL, KrystalContentProvider.COLUMN_NAME }, new int[] { R.id.item_image, R.id.item_text }, 0); // 创建一个ViewBinder,处理视图和数据库数据的绑定 SimpleCursorAdapter.ViewBinder binder = new SimpleCursorAdapter.ViewBinder() { @Override public boolean setViewValue(View view, Cursor cursor, int columnIndex) { // 此处cursor已经定位到目标行 Log.i("MainActivity", "columnIndex------" + columnIndex); /* * 自己的糟粕 LayoutInflater * inflater=LayoutInflater.from(MainActivity.this); View * rootView=inflater.inflate(R.layout.list_item, null); * if(columnIndex==1){ Log.i("MainActivity", "设置title"); * view=rootView.findViewById(R.id.item_text); * * }else if(columnIndex==3){ Log.i("MainActivity", "设置图片"); * view=rootView.findViewById(R.id.item_image); * //imageView.setImageURI * (Uri.parse("file:///android_asset/krystal012.jpeg")); String * uri=cursor.getString(columnIndex); Log.i("MainActivity", * "设置图片----"+uri); * //((ImageView)view).setImageURI(Uri.parse(cursor * .getString(columnIndex))); * Picasso.with(MainActivity.this).load * ("file:///android_asset/krystal012.jpeg" * ).into(((ImageView)view)); } * * return true; */ // 如果目标视图类型为ImageView if (view instanceof ImageView) { ImageView imageView = (ImageView) view; String value = cursor.getString(columnIndex); Log.i("MainActivity", "设置图片----" + value); /* * Uri uri=Uri.parse(value); imageView.setImageURI(uri); */ Picasso.with(MainActivity.this).load(value).resize(180, 180) .centerCrop().into(imageView); return true; } // 默认返回false; return false; } }; // 设置ViewBinder mAdapter.setViewBinder(binder); listView.setAdapter(mAdapter); // Start out with a progress indicator. // setListShown(false); // Prepare the loader. Either re-connect with an existing one, // or start a new one. // 暂时不用 // getLoaderManager().initLoader(0, null, this); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); MenuItem item = menu.add("Search"); item.setIcon(android.R.drawable.ic_menu_search); item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW); mSearchView = new MySearchView(this); mSearchView.setOnQueryTextListener(this); mSearchView.setOnCloseListener(this); mSearchView.setIconifiedByDefault(true); item.setActionView(mSearchView); return true; } public static class MySearchView extends SearchView { public MySearchView(Context context) { super(context); } // The normal SearchView doesn't clear its search text when // collapsed, so we will do this for it. @Override public void onActionViewCollapsed() { setQuery("", false); super.onActionViewCollapsed(); } } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } @Override public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) { // This is called when a new Loader needs to be created. This // sample only has one Loader, so we don't care about the ID. // First, pick the base URI to use depending on whether we are // currently filtering. Uri baseUri; if (mCurFilter != null) { baseUri = null; /* * baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, * Uri.encode(mCurFilter)); */ } else { baseUri = KrystalContentProvider.Content_URI; } // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. String select = "type=?"; return new CursorLoader(this, baseUri, null, select, new String[] { "cold" }, null); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { // Swap the new cursor in. (The framework will take care of closing the // old cursor once we return.) mAdapter.swapCursor(data); /* * // The list should now be shown. if (isResumed()) { * setListShown(true); } else { setListShownNoAnimation(true); } */ } @Override public void onLoaderReset(Loader<Cursor> arg0) { // This is called when the last Cursor provided to onLoadFinished() // above is about to be closed. We need to make sure we are no // longer using it. mAdapter.swapCursor(null); } @Override public boolean onQueryTextChange(String newText) { // Called when the action bar search text has changed. Update // the search filter, and restart the loader to do a new query // with this filter. String newFilter = !TextUtils.isEmpty(newText) ? newText : null; // Don't do anything if the filter hasn't actually changed. // Prevents restarting the loader when restoring state. if (mCurFilter == null && newFilter == null) { return true; } if (mCurFilter != null && mCurFilter.equals(newFilter)) { return true; } mCurFilter = newFilter; getLoaderManager().restartLoader(0, null, this); return true; } @Override public boolean onQueryTextSubmit(String arg0) { // Don't care about this. return true; } @Override public boolean onClose() { if (!TextUtils.isEmpty(mSearchView.getQuery())) { mSearchView.setQuery(null, true); } return true; }}
7.自己写的异步从asset加载图片工具类,虽然上面是通过Picasso加载的
package com.example.utils;import java.io.IOException;import java.io.InputStream;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Handler;import android.os.Message;import android.util.Log;public class LoadImage { public static void LoadImageFromAsset(final Context context,final String url,final LoadSuccessCallback callback){ //主线程handler传递bitmap对象 final Handler handler =new Handler(){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); Bitmap bitmap=(Bitmap)msg.obj; Log.i("TAG", "2.handler " ); //回调函数 callback.setImage(bitmap); } }; //新线程执行加载图片操作 new Thread(new Runnable() { @Override public void run() { try { InputStream is=context.getAssets().open(url); int length=is.available(); byte[] data=new byte[length]; is.read(data); Bitmap bitmap=BitmapFactory.decodeByteArray(data, 0, length); Message message=Message.obtain(); message.obj=bitmap; handler.sendMessage(message); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); } public interface LoadSuccessCallback{ public void setImage(Bitmap bitmap); }}
8.运行结果
0 0
- 简单的数据库交互展示
- 数据库交互的几个简单的对象
- ext简单的与数据库交互
- Web与数据库的简单交互
- 两个简单的Demo示例向读者展示Flash和ASP.NET交互原理以及过程
- pagerslidingtabstrip的简单展示
- Pagerslidingtabstrip的简单展示
- Python与数据库简单交互
- LISP 简单的数据库 3.4 改进用户交互
- Android客户端与数据库交互数据的简单学习
- 一些简单的android与sae服务器数据库交互代码
- php和数据库mysql的一些简单交互
- SpringMVC4+thymeleaf3的一个简单实例(篇五:页面和MySql的数据交互-展示以及存储)
- 简单的 bootstrap 效果展示
- 简单的商品列表展示
- FLEX 的简单交互
- 简单的输入输出交互
- 简单的点击交互
- html base64 img 图片显示
- Drozer – Android APP安全评估工具(附测试案例)
- Attempting to badge the application icon but haven't received permission解决方案
- MySQL语法大全
- 红黑树
- 简单的数据库交互展示
- java连接mysql
- Struts2 ValueStack
- cocos2dx画扇形
- 降维工具箱
- Cloud Foundry 部署问题(2)buildpack时间过长
- Spring MVC 简单demo1
- 个人面试题(oracle数据库开发)(一)
- LBP+DLBP+STLBP+VLBP