关闭

Android 通过ContentProvider数据库更新UI

221人阅读 评论(0) 收藏 举报
 

Android 通过ContentProvider数据库更新UI

 2120人阅读 评论(3) 收藏 举报
 分类:
 

目录(?)[+]

这篇用到的知识点有几个:SQLiteOpenHelper,Cursor,CursorAdapter,ContentProvider,ContentObserver

对于数据库的操控一般都是用SQLiteOpenHelper,创建该类实例,可以得到一个SQLiteDatabase,而实际上操作数据库用的还是这个。

(一)我们先看下SQLiteOpenHelper这个类的实例


[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.bvin.study.observer;  
  2.   
  3. import android.content.Context;  
  4. import android.database.sqlite.SQLiteDatabase;  
  5. import android.database.sqlite.SQLiteOpenHelper;  
  6.   
  7. public class DBHelper extends SQLiteOpenHelper{  
  8.       
  9.     public DBHelper(Context context){  
  10.         super(context,"cache",null,Config.DATA_VERSION);  
  11.     }  
  12.   
  13.     @Override  
  14.     public void onCreate(SQLiteDatabase db) {  
  15.         // TODO Auto-generated method stub  
  16.         db.execSQL("create table person(_id integer primary key autoincrement,name string,sex string,age integer)");  
  17.     }  
  18.   
  19.     @Override  
  20.     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
  21.         // TODO Auto-generated method stub  
  22.           
  23.     }  
  24.   
  25.       
  26.       
  27. }  


这个类主要负责数据库的创建和版本的更新管理。
一般情况下,是可以过去这个类的实例也就是SQLiteDatabase实例去做增删查改的工作。SQLiteDatabase已经封装了对数据库的各种操作方法,而且还提供了一个db.execSQL(sql, bindArgs)方法来执行原生sql语句,有人说这种方式比它封装的方法更高效。但是execSQL()是不返回值的,下面看下那些个方法都返回些什么值。

SQLiteDatabase

1.public long insert (String table, String nullColumnHack, ContentValues values)

这里是向一个表插入数据,values有把要插入的数据和表中的字段对应起来,返回的是插入到表中该行所在得行id。

2.public int update (String table, ContentValues values, String whereClause, String[] whereArgs)

这个方法后面的是按照什么样的条件去更新符合条件的记录,返回更新的记录所在行。

3.public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, StringorderBy, String limit)

返回查询到的结果集

4.public int delete (String table, String whereClause, String[] whereArgs)

返回删除的哪行

而查询可以 用异步查询AsyncQueryHandler ,其实这个类也可以执行增删查该,分别override每个方法来做出响应处理

(二)ContentProvider

这是Android四大组件之一,不需要手动实例化,只要在Androidmanifest.xml里面把ContentProvider注册上去就行。

 <provider android:name=".MyProvide" android:authorities="com.bvin.study.observer.MyProvide"/>


android:name即指定类名,android:authorities即绑定唯一的标识符,而这个一定要和URI的一样。

ContentProvider的uri形式跟域名很像:content://authorities//path,这个uri是非常重要的东西。

path可以表示某张表再后面可以指定某一行的某个字段,像/person/18/name就表示person表中第18个人的name

ui叫统一资源定位符,这样就唯一标识了这个资源,别的应用程序就可以用你的数据了,android系统本身就提供了大量的provider如短信,联系人等

 

好,uri讲完了就轮到ContentProvider了。

ContentProvider一般不主动构造,它跟Activity一样提供了一个入口方法。光有ContentProvider不行啊,所谓巧妇难为无米之炊啊。所以米在哪里呢,米就用我们做好的DBHelper。DBHelper获取数据库SQLiteDatabase,这个才是真正的数据库。再ContentProvider里覆盖操作数据库的各种方法,然后用SQLiteDatabase去执行各个操作。

 看看ContentProvider内部的实现

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.bvin.study.observer;  
  2.   
  3. import android.content.ContentProvider;  
  4. import android.content.ContentValues;  
  5. import android.database.Cursor;  
  6. import android.net.Uri;  
  7.   
  8. public class MyProvide extends ContentProvider{  
  9.       
  10.     DBHelper dbHelper;  
  11.   
  12.     @Override  
  13.     public int delete(Uri uri, String selection, String[] selectionArgs) {  
  14.         // TODO Auto-generated method stub  
  15.         return 0;  
  16.     }  
  17.   
  18.     @Override  
  19.     public String getType(Uri uri) {  
  20.         // TODO Auto-generated method stub  
  21.         return null;  
  22.     }  
  23.   
  24.     @Override  
  25.     public Uri insert(Uri uri, ContentValues values) {  
  26.         // TODO Auto-generated method stub  
  27.           
  28.         long rowId = -1;  
  29.         rowId =dbHelper.getWritableDatabase().insert(Config.TABLE_NAME, null, values);  
  30.         Uri cururi = Uri.withAppendedPath(Config.CONTENT_URI, rowId+"");  
  31.         this.getContext().getContentResolver().notifyChange(uri,null);  
  32.         return cururi;  
  33.     }  
  34.   
  35.     @Override  
  36.     public boolean onCreate() {  
  37.         // TODO Auto-generated method stub  
  38.         dbHelper = new DBHelper(getContext());  
  39.         return true;  
  40.     }  
  41.   
  42.     @Override  
  43.     public Cursor query(Uri uri, String[] projection, String selection,  
  44.             String[] selectionArgs, String sortOrder) {  
  45.         // TODO Auto-generated method stub  
  46.         return null;  
  47.     }  
  48.   
  49.     @Override  
  50.     public int update(Uri uri, ContentValues values, String selection,  
  51.             String[] selectionArgs) {  
  52.         // TODO Auto-generated method stub  
  53.         return 0;  
  54.     }  
  55.   
  56.       
  57. }  

这里仅用了插入这个方法,但外部是怎么调用的呢?用到是个叫ContentResolver,这个类可以通过Context上下文获取,ContentResolver也有insert(),update(),query().delete()方法,但ContentResolver的方法是暴露在外面的方法,真正执行的是ContetnProvider。ContentResolver就像一辆车它会前进,后退,转弯,刹车,而ContetnProvider就是司机,外面看到的车在转弯在刹车都是司机在操作,而这些功能司机有吗?没有司机不能代表车转弯刹车,这些核心的功能是汽车方向盘和刹车的功能,所以SQLiteDatabase就是方向盘咯,这个比喻可能不是很恰当。

 (三)ContentResolver

前面的都是功能接口服务的提供,接下来我们看如何去调用。这里用了一个ListActivity来调用以上定义的服务和数据可视化,主界面是个Listview,对数据库的操作用菜单来作用,四个菜单分别是增删查改。

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. @Override  
  2.     public boolean onCreateOptionsMenu(Menu menu) {  
  3.         // TODO Auto-generated method stub  
  4.           
  5.         menu.add(000"添加");  
  6.         menu.add(011"查询");  
  7.         menu.add(022"更改");  
  8.         menu.add(033"删除");  
  9.           
  10.         return super.onCreateOptionsMenu(menu);  
  11.     }  
  12.   
  13.     @Override  
  14.     public boolean onOptionsItemSelected(MenuItem item) {  
  15.         // TODO Auto-generated method stub  
  16.           
  17.         switch(item.getItemId()){  
  18.           
  19.         case 0:  
  20.             ContentValues cv = new ContentValues();  
  21.             cv.put("name""楚凌");  
  22.             getContentResolver().insert(Config.CONTENT_URI, cv);  
  23.               
  24.             break;  
  25.         case 1:  
  26.               
  27.             break;  
  28.         case 2:  
  29.             dbHelper.getWritableDatabase().execSQL("update "+Config.TABLE_NAME+" set name = 'chuling' where _id = 2");  
  30.             adapter.notifyDataSetChanged();  
  31.             break;  
  32.         case 3:  
  33.             dbHelper.getWritableDatabase().delete(Config.TABLE_NAME, nullnull);  
  34.             break;  
  35.           
  36.         }  
  37.           
  38.         return super.onOptionsItemSelected(item);  
  39.     }  

如果按以上代码,执行插入操作listview是不能及时先出来的,重启程序之后就可以看到新加的项。那要怎样才能插入一个就显示一个也就是更新数据及时刷新UI界面,因为ListView绑定的是CursorAdapter而这个cursor是充数据库查询出来的,所以要做的事情有两个。一个是数据源更新然后就是适配器去通知ui数据已改变,cursor就要重新查询一遍,或者adapter更换游标,然后再调用adapter.notifyDataSetChanged();但是cursor.requery()执行会影响效率,而光靠adapter.notifyDataSetChanged()界面是不会更新的,本来想用ContentObserver来实现,最后还是感觉不适合,有没有数据库变动及时更新Listview的良策???

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. DBHelper dbHelper  = null;  
  2.     SimpleCursorAdapter adapter;  
  3.     Cursor cursor;  
  4.     Handler handler;  
  5.     MyObserver observer;  
  6.     @Override  
  7.     public void onCreate(Bundle savedInstanceState) {  
  8.         super.onCreate(savedInstanceState);  
  9.         //setContentView(R.layout.main);  
  10.         dbHelper = new DBHelper(this);  
  11.         handler = new Handler(){  
  12.   
  13.             @Override  
  14.             public void handleMessage(Message msg) {  
  15.                 // TODO Auto-generated method stub  
  16.                 super.handleMessage(msg);  
  17.                 if(msg.what==2013){  
  18.                     if(cursor!=null&&!cursor.isClosed()&&adapter!=null){  
  19.                         adapter.notifyDataSetChanged();  
  20.                     }  
  21.                 }  
  22.             }  
  23.               
  24.         };  
  25.          
  26.           
  27.         cursor = dbHelper.getReadableDatabase().rawQuery("select * from "+Config.TABLE_NAME, null);  
  28.         adapter = new SimpleCursorAdapter(this,android.R.layout.simple_list_item_1,cursor, new String[]{"name"}, new int[]{android.R.id.text1});  
  29.         setListAdapter(adapter);  
  30.           
  31.         observer = new MyObserver(this,handler,cursor);  
  32.         getContentResolver().registerContentObserver(Config.CONTENT_URI, false, observer);  
  33.           
  34.     }  

其实这里看到Config.CONTENT_URI,其实这个就是指向的数据库的路径,就是牵着风筝的一条线,牵着线的手是ContentResolver,风筝当然就是ContetnProvider咯!
这里没看cursor.requery()哈,其实这个我已经放在ContentObserver里了。上面还有个handler,这个handler是用来注册ContentObserver的,这里将会处理观察者发出的消息。

(四) ContentObserver

这个类的构造方法必须有个Handler的参数来进行通信,还有个必须的就是必须覆盖onChanged()方法,用handler去发送message跟Activity去通信。

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.bvin.study.observer;  
  2.   
  3. import android.content.AsyncQueryHandler;  
  4. import android.content.ContentResolver;  
  5. import android.content.Context;  
  6. import android.database.ContentObserver;  
  7. import android.database.Cursor;  
  8. import android.net.Uri;  
  9. import android.os.AsyncTask;  
  10. import android.os.Handler;  
  11. import android.os.Looper;  
  12. import android.os.Message;  
  13.   
  14. public class MyObserver extends ContentObserver{  
  15.   
  16.     private Handler handler;  
  17.     private Cursor cursor;  
  18.     private Context context;  
  19.     public MyObserver(Context context,Handler handler,Cursor cursor){  
  20.         super(handler);  
  21.         this.context = context;  
  22.         this.handler = handler;  
  23.         this.cursor = cursor;  
  24.           
  25.     }  
  26.       
  27.     @Override  
  28.     public void onChange(boolean selfChange) {  
  29.         // TODO Auto-generated method stub  
  30.         super.onChange(selfChange);  
  31.           
  32.         cursor.requery();  
  33.         handler.sendEmptyMessage(2013);  
  34.     }  
  35.   
  36.       
  37.       
  38. }  

我这里把cursor传进去,目的就是注册的URI指向的数据库更新时,就在onChanged()方法里再查询一边,然后Activity里的Handler处理消息的方法里用Adapter通知一下,界面就会及时更新了。
但是用这个去更新Listview也不太现实,handler里处理一下其他的ui元素还是可以的,比如插入数据,就蹦出个对话框“数据插入完毕”。。。

下面还是发下全部的代码,貌似还不可以传附件。。

主界面:MainActivity.java

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.bvin.study.observer;  
  2.   
  3. import android.app.ListActivity;  
  4. import android.content.AsyncQueryHandler;  
  5. import android.content.ContentResolver;  
  6. import android.content.ContentValues;  
  7. import android.database.Cursor;  
  8. import android.net.Uri;  
  9. import android.os.Bundle;  
  10. import android.os.Handler;  
  11. import android.os.Looper;  
  12. import android.os.Message;  
  13. import android.view.Menu;  
  14. import android.view.MenuItem;  
  15. import android.widget.SimpleCursorAdapter;  
  16.   
  17. public class MainActivity extends ListActivity {  
  18.     /** Called when the activity is first created. */  
  19.       
  20.     DBHelper dbHelper  = null;  
  21.     SimpleCursorAdapter adapter;  
  22.     Cursor cursor;  
  23.     Handler handler;  
  24.     MyObserver observer;  
  25.     @Override  
  26.     public void onCreate(Bundle savedInstanceState) {  
  27.         super.onCreate(savedInstanceState);  
  28.         //setContentView(R.layout.main);  
  29.         dbHelper = new DBHelper(this);  
  30.         handler = new Handler(){  
  31.   
  32.             @Override  
  33.             public void handleMessage(Message msg) {  
  34.                 // TODO Auto-generated method stub  
  35.                 super.handleMessage(msg);  
  36.                 if(msg.what==2013){  
  37.                     if(cursor!=null&&!cursor.isClosed()&&adapter!=null){  
  38.                         adapter.notifyDataSetChanged();  
  39.                     }  
  40.                 }  
  41.             }  
  42.               
  43.         };  
  44.          
  45.           
  46.         cursor = dbHelper.getReadableDatabase().rawQuery("select * from "+Config.TABLE_NAME, null);  
  47.         adapter = new SimpleCursorAdapter(this,android.R.layout.simple_list_item_1,cursor, new String[]{"name"}, new int[]{android.R.id.text1});  
  48.         setListAdapter(adapter);  
  49.           
  50.         observer = new MyObserver(this,handler,cursor);  
  51.         getContentResolver().registerContentObserver(Config.CONTENT_URI, false, observer);  
  52.           
  53.     }  
  54.   
  55.     @Override  
  56.     public boolean onCreateOptionsMenu(Menu menu) {  
  57.         // TODO Auto-generated method stub  
  58.           
  59.         menu.add(0, 0, 0, "添加");  
  60.         menu.add(0, 1, 1, "查询");  
  61.         menu.add(0, 2, 2, "更改");  
  62.         menu.add(0, 3, 3, "删除");  
  63.           
  64.         return super.onCreateOptionsMenu(menu);  
  65.     }  
  66.   
  67.     @Override  
  68.     public boolean onOptionsItemSelected(MenuItem item) {  
  69.         // TODO Auto-generated method stub  
  70.           
  71.         switch(item.getItemId()){  
  72.           
  73.         case 0:  
  74.             ContentValues cv = new ContentValues();  
  75.             cv.put("name""楚凌");  
  76.             getContentResolver().insert(Config.CONTENT_URI, cv);  
  77.               
  78.             break;  
  79.         case 1:  
  80.               
  81.             break;  
  82.         case 2:  
  83.             dbHelper.getWritableDatabase().execSQL("update "+Config.TABLE_NAME+" set name = 'chuling' where _id = 2");  
  84.             adapter.notifyDataSetChanged();  
  85.             break;  
  86.         case 3:  
  87.             dbHelper.getWritableDatabase().delete(Config.TABLE_NAME, null, null);  
  88.             break;  
  89.           
  90.         }  
  91.           
  92.         return super.onOptionsItemSelected(item);  
  93.     }  
  94.   
  95.     @Override  
  96.     protected void onDestroy() {  
  97.         // TODO Auto-generated method stub  
  98.         super.onDestroy();  
  99.         if(dbHelper!=null){  
  100.             dbHelper.close();  
  101.         }  
  102.          getContentResolver().unregisterContentObserver(observer);  
  103.     }  
  104.       
  105. }  

MyProvider.java

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.bvin.study.observer;  
  2.   
  3. import android.content.ContentProvider;  
  4. import android.content.ContentValues;  
  5. import android.database.Cursor;  
  6. import android.net.Uri;  
  7.   
  8. public class MyProvide extends ContentProvider{  
  9.       
  10.     DBHelper dbHelper;  
  11.   
  12.     @Override  
  13.     public int delete(Uri uri, String selection, String[] selectionArgs) {  
  14.         // TODO Auto-generated method stub  
  15.         return 0;  
  16.     }  
  17.   
  18.     @Override  
  19.     public String getType(Uri uri) {  
  20.         // TODO Auto-generated method stub  
  21.         return null;  
  22.     }  
  23.   
  24.     @Override  
  25.     public Uri insert(Uri uri, ContentValues values) {  
  26.         // TODO Auto-generated method stub  
  27.           
  28.         long rowId = -1;  
  29.         rowId =dbHelper.getWritableDatabase().insert(Config.TABLE_NAME, null, values);  
  30.         Uri cururi = Uri.withAppendedPath(Config.CONTENT_URI, rowId+"");  
  31.         this.getContext().getContentResolver().notifyChange(uri,null);  
  32.         return cururi;  
  33.     }  
  34.   
  35.     @Override  
  36.     public boolean onCreate() {  
  37.         // TODO Auto-generated method stub  
  38.         dbHelper = new DBHelper(getContext());  
  39.         return true;  
  40.     }  
  41.   
  42.     @Override  
  43.     public Cursor query(Uri uri, String[] projection, String selection,  
  44.             String[] selectionArgs, String sortOrder) {  
  45.         // TODO Auto-generated method stub  
  46.         return null;  
  47.     }  
  48.   
  49.     @Override  
  50.     public int update(Uri uri, ContentValues values, String selection,  
  51.             String[] selectionArgs) {  
  52.         // TODO Auto-generated method stub  
  53.         return 0;  
  54.     }  
  55.   
  56.       
  57. }  

DBHelper.java

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.bvin.study.observer;  
  2.   
  3. import android.content.Context;  
  4. import android.database.sqlite.SQLiteDatabase;  
  5. import android.database.sqlite.SQLiteOpenHelper;  
  6.   
  7. public class DBHelper extends SQLiteOpenHelper{  
  8.       
  9.     public DBHelper(Context context){  
  10.         super(context,"cache",null,Config.DATA_VERSION);  
  11.     }  
  12.   
  13.     @Override  
  14.     public void onCreate(SQLiteDatabase db) {  
  15.         // TODO Auto-generated method stub  
  16.         db.execSQL("create table person(_id integer primary key autoincrement,name string,sex string,age integer)");  
  17.           
  18.     }  
  19.   
  20.     @Override  
  21.     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
  22.         // TODO Auto-generated method stub  
  23.           
  24.     }  
  25.   
  26.       
  27.       
  28. }  

MyObserver.java

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.bvin.study.observer;  
  2.   
  3. import android.content.AsyncQueryHandler;  
  4. import android.content.ContentResolver;  
  5. import android.content.Context;  
  6. import android.database.ContentObserver;  
  7. import android.database.Cursor;  
  8. import android.net.Uri;  
  9. import android.os.AsyncTask;  
  10. import android.os.Handler;  
  11. import android.os.Looper;  
  12. import android.os.Message;  
  13.   
  14. public class MyObserver extends ContentObserver{  
  15.   
  16.     private Handler handler;  
  17.     private Cursor cursor;  
  18.     private Context context;  
  19.     public MyObserver(Context context,Handler handler,Cursor cursor){  
  20.         super(handler);  
  21.         this.context = context;  
  22.         this.handler = handler;  
  23.         this.cursor = cursor;  
  24.           
  25.     }  
  26.       
  27.     @Override  
  28.     public void onChange(boolean selfChange) {  
  29.         // TODO Auto-generated method stub  
  30.         super.onChange(selfChange);  
  31.           
  32.         cursor.requery();  
  33.         handler.sendEmptyMessage(2013);  
  34.     }  
  35.   
  36.       
  37.       
  38. }  

Config.java

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.bvin.study.observer;  
  2.   
  3. import android.net.Uri;  
  4.   
  5. public class Config {  
  6.   
  7.     public static final String AOTHORITY = "com.bvin.study.observer.MyProvide";  
  8.     public static final String TABLE_NAME = "person";  
  9.     public static final Uri CONTENT_URI = Uri.parse("content://"+AOTHORITY+"/"+TABLE_NAME);  
  10.     public static final int DATA_VERSION =1;  
  11. }  

AndroidManifest.xml

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="com.bvin.study.observer"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  
  6.   
  7.     <uses-sdk android:minSdkVersion="8" />  
  8.   
  9.     <application  
  10.         android:icon="@drawable/ic_launcher"  
  11.         android:label="@string/app_name" >  
  12.         <activity  
  13.             android:name=".MainActivity"  
  14.             android:label="@string/app_name" >  
  15.             <intent-filter>  
  16.                 <action android:name="android.intent.action.MAIN" />  
  17.   
  18.                 <category android:name="android.intent.category.LAUNCHER" />  
  19.             </intent-filter>  
  20.         </activity>  
  21.           
  22.         <provider android:name=".MyProvide" android:authorities="com.bvin.study.observer.MyProvide"/>  
  23.     </application>  
  24.   
  25. </manifest>  
0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

Android ContentProvider封装数据库和文件读写总结

本文是我各处东拼西凑加上自己实践的一个ContentProvider使用总结,留做后用,主要介绍ContentProvider的集成方法。 一、综述 ContentProvider是Android四...
  • u013478336
  • u013478336
  • 2016-02-23 12:04
  • 1537

Android ContentProvider和ContentObserver 监控数据库变化 简单使用说明

在网上很难找到ContentObserver的使用说明,大多都是监控系统的数据库的变化,或者很多文章都是ContentProvider和ContentObserver一起说明,导致内容很多,很乱。那问...
  • shell812
  • shell812
  • 2015-11-11 14:16
  • 1669

ContentProvider之数据库更新UI

---恢复内容开始--- 快过年了,明年还要找工作。。。。。 之前写过很多android各种知识点的demo,但是过了很久没用到就会忘掉。 现在复习一下。 这篇用到的知识点有几个:SQLite...
  • glen1943
  • glen1943
  • 2013-02-19 09:29
  • 324

ContentProvider数据库共享之——读写权限与数据监听

前言:随着工作的时间越来越长,越来越觉得自己学知识的速度太慢,原定的两年,现在已经过了快九个月了,仍然对很多知识懵懵懂懂,对JAVA理解的还是不够彻底,现在终于有点时间能放纵地看一些自己感兴趣的东西了...
  • harvic880925
  • harvic880925
  • 2015-03-26 16:39
  • 12252

Android异步更新UI的几种方法

前言:我们知道在android开发中不能在非ui线程的其他线程中更新ui,但是,有的时候我们需要在代码中执行一些诸如访问网络、查询数据库等耗时操作,为了不阻塞ui线程,我们时常会开启一个新的线程(工作...
  • ydxlt
  • ydxlt
  • 2016-04-26 12:37
  • 6181

Android ContentProvider之联系人数据库及操作

通讯录数据库的主要表之间架构关系: 第一层:Data层,每种独立的数据类型占一行。具体哪些独立的数据可以占一行,可以在mimetypes这张表中找到, 原生Android的系统 一共12...
  • u011240877
  • u011240877
  • 2015-03-24 17:04
  • 1232

android通过观察者模式实现更新UI

观察者模式: §定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 相信大家对观察者模式应该不陌生。。就不多介绍啦,上代码: /**...
  • jycboy
  • jycboy
  • 2015-05-27 00:46
  • 957

ContentProvider数据库共享之——实例讲解

前言:现在这段时间没这么忙了,要抓紧时间把要总结的知识沉淀下来,今年重新分了项目组,在新项目中应该不会那么忙了,看来有时间来学一些自己的东西了。现在而言,我需要的是时间。只要不断的努力,总有一天,你会...
  • u014628886
  • u014628886
  • 2016-07-26 11:47
  • 578

Android 更新UI方法的深度解析

Android开发中,我们总是会遇到更新UI的场景。如果,我们直接在子线程中更新UI,那么会报错!提示我们,要在主线程中更新UI。那么具体更新UI有几种方法呢?下面就来列举这几种更新UI的方法。 1....
  • zxw136511485
  • zxw136511485
  • 2016-11-03 14:22
  • 1985

Android更新Ui的几种方法和见解

先贴一个我们刚做Android开发时候最容易遇到的一个错误异常 AndroidRuntimeException :“Only the original thread that created a vi...
  • u011254308
  • u011254308
  • 2015-04-18 19:29
  • 8774
    个人资料
    • 访问:29876次
    • 积分:588
    • 等级:
    • 排名:千里之外
    • 原创:24篇
    • 转载:50篇
    • 译文:0篇
    • 评论:1条
    文章分类
    最新评论