Android四大组件之三:ContentProvider数据共享
2015-08-09 20:43
567 查看
1.ContentProvider数据共享 --- Android四大组件之一
[1]概念:数据共享本身不是数据库,它是为Sqlite关系数据库提供了共享功能。
共享数据库的优点:节约资源,可以将多个应用程序需要的数据库做成一个共享数据库。例如联系人数据库,多媒体数据库。
[2]制作共享数据库的步骤
1.定义一个类,继承ContentProvider
2.在清单文件中添加privider标签 必须填写的属性name, authorities(共享数据库地址)(命名规则:应用程序的包名+组件的类名)
3.重写ContentProvider类中的onCreate方法,创建关系数据库。给关系数据库添加共享功能。
[3]操作共享数据库
ContentResolver --- 操作共享数据库
相关方法 --- insert, update, delete, query方法。
当用户调用以上方法时,系统会自动调用ContentProvider中的insert, update, delete, query方法
[4]操作系统联系人数据库地址 ContactsContract.Contacts.CONTENT_URI
2.Android进程与多线程
[1]一个android应用程序运行在一个独立的进程中,运行在一个独立的dvk中,拥有独立的Linux user id。
android进程的名字为该应用程序的包名
[2]android程序启动后,默认开启一个主线程 (UI线程)
UI线程负责显示界面,负责按键响应,屏幕的触摸响应等。
[3]不能在UI主线程中做耗时的操作。
如果在UI主线程中做耗时的操作,超过5s,系统会报ANR错误。(Application not respond)
如何避免ANR错误,将耗时的操作放在子线程中完成。
[4]耗时的操作:复杂的运算,联网。
[5]Widget控件只能被UI主线程操作,如果子线程操作,会抛出异常。
[6]Handler对象:负责在子线程发送消息 handler.sendMessage(msg)
负责在主线程中接收消息 handlerMessage(Message msg)
将子线程中的计算结果绑定在消息对象 msg.arg1 = count
对消息进行分类 msg.what = 2
2.异步任务 AsynicTask
[1]概念:是对Handler机制的高度封装
[2]Handler模式和AsyncTask模式的对比:
Handler模式为每一个任务创建了一个新线程,任务完成后通过handler对象向UI主线程发送消息,完成界面的更新。
这种方式对于整个过程的控制比较精细,但是也有缺点,例如代码相对臃肿,在多个任务同时执行时,不易对线程进行精确控制。
为了简化操作,使用AsyncTask对Handler机制进行封装。
[3]注意:1.异步任务对象必须在UI主线程中创建
2.不能手动调用异步任务中的方法 doInBackground方法。
3.不能再doInBackground方法中,操作widget控件,因为该方法被子线程调用。
4.一个异步任务对象,只能执行一次。
[1]概念:数据共享本身不是数据库,它是为Sqlite关系数据库提供了共享功能。
共享数据库的优点:节约资源,可以将多个应用程序需要的数据库做成一个共享数据库。例如联系人数据库,多媒体数据库。
[2]制作共享数据库的步骤
1.定义一个类,继承ContentProvider
2.在清单文件中添加privider标签 必须填写的属性name, authorities(共享数据库地址)(命名规则:应用程序的包名+组件的类名)
3.重写ContentProvider类中的onCreate方法,创建关系数据库。给关系数据库添加共享功能。
[3]操作共享数据库
ContentResolver --- 操作共享数据库
相关方法 --- insert, update, delete, query方法。
当用户调用以上方法时,系统会自动调用ContentProvider中的insert, update, delete, query方法
[4]操作系统联系人数据库地址 ContactsContract.Contacts.CONTENT_URI
package com.farsight.contentProvider; import android.app.Activity; import android.content.ContentResolver; import android.content.ContentValues; import android.net.Uri; import android.os.Bundle; public class Android_28_ContentProviderActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //向共享数据添加记录 ContentResolver resolver = this.getContentResolver(); // Uri 网址"http://www.baidu.com" // Uri 共享数据库地址"content://" //共享数据库地址 Uri url = Uri.parse("content://com.farsight.contentProiver.MyProvider"); ContentValues values = new ContentValues(); values.put(MyProvider.NAME, "ivy"); values.put(MyProvider.SCORE, 100); //系统自动调用Myprovider中的insert方法 resolver.insert(url, values); } }
package com.farsight.contentProvider; import android.content.ContentProvider; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; import android.net.Uri; import android.util.Log; //共享数据库对象在安装应用程序时创建 //系统自动调用onCreate方法 public class MyProvider extends ContentProvider { public static final String TABLE_NAME = "student"; public static final String NAME = "name"; public static final String SCORE = "score"; private SQLiteDatabase db; @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub int row = db.delete(TABLE_NAME, selection, selectionArgs); return row; } @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 db.insert(TABLE_NAME, null, values); Log.e("Test", "insert"); return uri; } // 系统自动调用该方法 @Override public boolean onCreate() { // TODO Auto-generated method stub // 创建关系数据库 MySqliteOpenHelper mySqlite = new MySqliteOpenHelper(this.getContext(), TABLE_NAME, null, 1); //创建表格 db = mySqlite.getWritableDatabase(); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub Cursor cursor = db.query(TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder); return cursor; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub int row = db.update(TABLE_NAME, values, selection, selectionArgs); return row; } //数据库创建帮助类 class MySqliteOpenHelper extends SQLiteOpenHelper { public MySqliteOpenHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); // TODO Auto-generated constructor stub } @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub String sql = "create table " + TABLE_NAME + " (id integer primary key autoincrement, " + NAME + " char(20), " + SCORE + " integer)"; // 执行数据库语言, 创建表格 db.execSQL(sql); Log.e("Test", "创建表格"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub } } }
2.Android进程与多线程
[1]一个android应用程序运行在一个独立的进程中,运行在一个独立的dvk中,拥有独立的Linux user id。
android进程的名字为该应用程序的包名
[2]android程序启动后,默认开启一个主线程 (UI线程)
UI线程负责显示界面,负责按键响应,屏幕的触摸响应等。
[3]不能在UI主线程中做耗时的操作。
如果在UI主线程中做耗时的操作,超过5s,系统会报ANR错误。(Application not respond)
如何避免ANR错误,将耗时的操作放在子线程中完成。
[4]耗时的操作:复杂的运算,联网。
[5]Widget控件只能被UI主线程操作,如果子线程操作,会抛出异常。
[6]Handler对象:负责在子线程发送消息 handler.sendMessage(msg)
负责在主线程中接收消息 handlerMessage(Message msg)
将子线程中的计算结果绑定在消息对象 msg.arg1 = count
对消息进行分类 msg.what = 2
package com.farsight.count; import java.util.ArrayList; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; import android.widget.TextView; public class Android_32_CountActivity extends Activity implements OnClickListener, Runnable { Button btn; TextView tv; boolean isRun; ArrayList<String> data = new ArrayList<String>(); ArrayAdapter<String> adapter; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btn = (Button) findViewById(R.id.button1); btn.setOnClickListener(this); findViewById(R.id.button2).setOnClickListener(this); findViewById(R.id.button3).setOnClickListener(this); tv = (TextView) findViewById(R.id.textView1); ListView listView = (ListView) findViewById(R.id.listView1); adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, data); listView.setAdapter(adapter); } @Override public void onClick(View v) { // TODO Auto-generated method stub if (v.getId() == R.id.button1) { btn.setEnabled(false); isRun = true; new Thread(this).start(); } else if (v.getId() == R.id.button2) { btn.setEnabled(true); isRun = false; }else if(v.getId() == R.id.button3){ //每隔2s新增一个item项。 new Thread(new MyRun()).start(); } } int countItem; class MyRun implements Runnable{ @Override public void run() { // TODO Auto-generated method stub while(countItem < 10){ countItem++; data.add(String.valueOf(countItem)); //参数 what 表示消息类型 handler.sendEmptyMessage(2); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } int count = 0; @Override public void run() { // TODO Auto-generated method stub while (isRun) { count++; // tv.setText(String.valueOf(count)); //在子线程中发送消息 Message msg = handler.obtainMessage(); //将count值赋值给消息对象 msg.arg1 = count; msg.what = 1; //给当前消息设置类型 handler.sendMessage(msg); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } MyHandler handler = new MyHandler(); class MyHandler extends Handler{ //当主线程收到消息时,自动调用该方法 @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); //what 表示消息的种类 if(msg.what == 2){ adapter.notifyDataSetChanged(); }else if(msg.what == 1){ int count = msg.arg1; tv.setText(String.valueOf(count)); } } } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); isRun = false; } }
2.异步任务 AsynicTask
[1]概念:是对Handler机制的高度封装
[2]Handler模式和AsyncTask模式的对比:
Handler模式为每一个任务创建了一个新线程,任务完成后通过handler对象向UI主线程发送消息,完成界面的更新。
这种方式对于整个过程的控制比较精细,但是也有缺点,例如代码相对臃肿,在多个任务同时执行时,不易对线程进行精确控制。
为了简化操作,使用AsyncTask对Handler机制进行封装。
[3]注意:1.异步任务对象必须在UI主线程中创建
2.不能手动调用异步任务中的方法 doInBackground方法。
3.不能再doInBackground方法中,操作widget控件,因为该方法被子线程调用。
4.一个异步任务对象,只能执行一次。
package com.farsight.asynctask; import java.util.ArrayList; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; public class Android_33_AsynicTaskActivity extends Activity implements OnClickListener { MyTask task; ArrayList<String> data = new ArrayList<String>(); ArrayAdapter<String> adapter; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); findViewById(R.id.button1).setOnClickListener(this); findViewById(R.id.button2).setOnClickListener(this); findViewById(R.id.button3).setOnClickListener(this); TextView tv = (TextView) findViewById(R.id.textView1); task = new MyTask(tv); ListView listView = (ListView) findViewById(R.id.listView1); adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, data); listView.setAdapter(adapter); } @Override public void onClick(View v) { // TODO Auto-generated method stub if (v.getId() == R.id.button1) { // 启动异步任务,开启计数器 task.setRun(true); task.execute(); } else if (v.getId() == R.id.button2) { task.setRun(false); } else if (v.getId() == R.id.button3) { new AsyncTask<Integer, Integer, Void>() { @Override protected Void doInBackground(Integer... params) { // TODO Auto-generated method stub int count = 0; while (count < params[0]) { count++; publishProgress(count); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return null; } protected void onProgressUpdate(Integer... values) { int count = values[0]; data.add(String.valueOf(count)); adapter.notifyDataSetChanged(); } }.execute(10); } } }
package com.farsight.asynctask; import android.os.AsyncTask; import android.widget.TextView; //Params 启动异步任务的输入参数类型 //Progress 异步任务执行的进度 //Result 异步任务的结果 public class MyTask extends AsyncTask<Void, Integer, Void> { private TextView tv; private boolean isRun; public MyTask(TextView tv) { // TODO Auto-generated constructor stub this.tv = tv; } //用户启动异步任务时,自动调用该方法 //该方法被子线程调用,用户可以将耗时的操作放在里面 @Override protected Void doInBackground(Void... params) { // TODO Auto-generated method stub int count = 0; while(isRun){ count++; //发布进度,系统自动调用onProgressUpdate方法,更新进度 publishProgress(count); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return null; } //更新进度 //该方法被UI主线程调用 @Override protected void onProgressUpdate(Integer... values) { // TODO Auto-generated method stub int count = values[0]; tv.setText(String.valueOf(count)); super.onProgressUpdate(values); } public void setRun(boolean isRun) { this.isRun = isRun; } }
相关文章推荐
- 代码获取Android版本等信息
- Android数据存储结构
- 关于Android数据存储方式(一)——SharedPreferences
- Android基础知识----01
- Android:实现EditText在获得焦点后消去hint,失去焦点后再显示原来的hint
- android分辨率 尺寸 dpi换算
- Android兼容性测试框架(CTS)手册
- Android基础之px,dp,sp对比以及应用
- Android TextView属性大全
- Android编译系统环境初始化过程分析
- Android OOM异常解决方案
- Android ANR异常解决方案
- Android源代码编译命令m/mm/mmm/make分析
- android 取消标题 程序意外停解决方法
- Android-Universal-Image-Loader三大组件DisplayImageOptions、ImageLoader、ImageLoaderConfiguration详解
- android图片的异步加载和双缓存学习笔记——DisplayImageOptions
- Android在onCreate()中获得控件尺寸
- Android-扩展BaseAdapter实现progressBar下载
- android多线程断点续传下载
- 说一说Android的工程目录结构