简单的数据库交互展示

来源:互联网 发布: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
原创粉丝点击