Android四大组件之三:ContentProvider数据共享

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
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 data = new ArrayList();
	ArrayAdapter 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(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 data = new ArrayList();
	ArrayAdapter 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(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() {

				@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 {

	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应用开发)