Android自学笔记-13-ContentObserver内容观察者

很久都没有更新博客了,最近在忙着公司的培训,一方面是有点忙,一方面是自己懒,所以一直没更新。好了,言归正传,今天简单的介绍一下Android中的ContentObserver。

ContentObserver翻译成中文就是内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理。ContentObserver一般和系统或第三方程序提供的Provider一起使用,这些Provider一般情况下会有一个Uri,然后ContentObserver就去监听这些Uri数据的变化,然后做出相应的处理。

使用ContentObserver的步骤我这里总结如下:

1 首先创建一个ContentObserver的子类,然后实现里面的onChange方法,监听的Uri中的数据发生变化的时候,会调用onchange方法。

2 注册ContentObserver

下面简单的列出例子代码:

ContentObserver的子类

package com.qin.contentobserver;

import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.provider.*;
import android.provider.Settings.SettingNotFoundException;
import android.util.Log;


//用来观察system表里飞行模式所在行是否发生变化 , “行”内容观察者
public class AirplaneContentObserver extends ContentObserver {

	private static String TAG = "AirplaneContentObserver" ;
	
	private static int MSG_AIRPLANE = 1 ;
	
	private Context mContext;    
    private Handler mHandler ;  //此Handler用来更新UI线程
    
	public AirplaneContentObserver(Context context, Handler handler) {
		super(handler);
		mContext = context;
		mHandler = handler ;
	}

	/**
	 * 当所监听的Uri发生改变时,就会回调此方法
	 * 
	 * @param selfChange 此值意义不大 一般情况下该回调值false
	 */
	@Override
	public void onChange(boolean selfChange) {
        Log.i(TAG, "-------------the airplane mode has changed-------------");
        
		// 系统是否处于飞行模式下
		try {
			int isAirplaneOpen = Settings.System.getInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON);
		    Log.i(TAG, " isAirplaneOpen -----> " +isAirplaneOpen) ;
		    mHandler.obtainMessage(MSG_AIRPLANE,isAirplaneOpen).sendToTarget() ;
		}
		catch (SettingNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}

这里面我们可以看出我们定义了一个带参数的构造方法,其中第二个参数是Handler,这是因为我们自定义的AirplaneContentObserver,在程序运行的时候,是非主线程,在Android中非主线程是无法修改UI的。所以这里我们如果想要去修改UI需要先发送一个消息给Handler,然后主线程中的Handler在接收到发送过来的消息之后,会调用handleMessage方法,然后再去做一些处理或者更新UI,所以这里的Handler参数,需要在主线程中创建,然后再调用的时候传递到该类的对象里面。

下面给出MainActivity.java类:

package com.qin.contentobserver;

import android.app.Activity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.*;
import android.util.Log;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {

	private TextView tvAirplane;
	private EditText etSmsoutbox;

	// Message 类型值
	private static final int MSG_AIRPLANE = 1;
	private static final int MSG_OUTBOXCONTENT = 2;

	private AirplaneContentObserver airplaneCO;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		tvAirplane = (TextView) findViewById(R.id.tvAirplane);
		etSmsoutbox = (EditText) findViewById(R.id.smsoutboxContent);

		// 创建两个对象
		airplaneCO = new AirplaneContentObserver(this, mHandler);
		
		//注册内容观察者
		registerContentObservers() ;
	}

	private void registerContentObservers() {
		// 通过调用getUriFor 方法获得 system表里的"飞行模式"所在行的Uri
		Uri airplaneUri = Settings.System.getUriFor(Settings.Global.AIRPLANE_MODE_ON);
		// 注册内容观察者
		// 第二个参数false 为精确匹配
		getContentResolver().registerContentObserver(airplaneUri, false, airplaneCO);
	}

	private Handler mHandler = new Handler() {

		public void handleMessage(Message msg) {
			
			System.out.println("---mHanlder----");
			switch (msg.what) {
			case MSG_AIRPLANE:
				int isAirplaneOpen = (Integer) msg.obj;
				if (isAirplaneOpen != 0)
					tvAirplane.setText("飞行模式已打开");
				else if (isAirplaneOpen == 0)
					tvAirplane.setText("飞行模式已关闭");
				break;
			default:
				break;
			}
		}
	};
}
在上面的代码中我们注册了一个监听手机飞行模式变化的一个内容观察者,当我们修改我们飞行模式的值得时候,在页面上显示的结果也会发生相应的改变。

例子工程的下载地址:http://download.csdn.net/detail/mengxiangyue/7169579

Android自学笔记-13-ContentObserver内容观察者,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。