Android Demo之旅 Activity、Service、BroadCast实现计数统计

时间匆匆,转眼就是大半个月过去了,学习android的道理上艰苦而漫长呀!!自己写了很多的小demo,总结总结,也在博客里面留点足迹吧!

源代码下载:http://download.csdn.net/detail/harderxin/7761401     参考实例:老罗博客

实现功能:统计计数,我们可能有很多种方式来实现它,但是这个实例运用了Activity、Service、BroadcastReceiver在android中三个大知识点,所以觉得它比较有参考价值;

可学知识点:1)Activity、Service的生命周期;2)bindService的用法;3)代码注册BroadcastReceiver;4)学习使用异步加载类AsyncTask

功能逻辑:参考下面流程图:

Android Demo之旅   Activity、Service、BroadCast实现计数统计

启动Activity后,在相应的Activity生命周期中绑定Service和注册广播接收者,当用户点击按钮时,启动AsyncTask异步处理逻辑,也就是加数,然后将结果时时发送到广播中,广播接收者接到广播后时时更新Activity;

实现功能:

Android Demo之旅   Activity、Service、BroadCast实现计数统计

功能详解:因为有源代码,所以我只讲解该小应用的核心代码:

1)启动Activity,绑定Service

        //通过bindService方法会将计数器服务CounterService启动起来
        //serviceConn为ServiceConnection的一个实例,服务器启动起来后
        //系统会调用ServiceConnection里面的onServiceConnected方法将Service中
        //的CounterBinder对象传回来,得到相应的Service
        //当我们调用unBindService停止服务时,会调用其onServiceDisconnected方法
        Intent bindIntent=new Intent(MainActivity.this,CounterService.class);
        bindService(bindIntent, serviceConn, Context.BIND_AUTO_CREATE);
    //创建Service连接对象
    private ServiceConnection serviceConn=new ServiceConnection() {
    	
		@Override
		public void onServiceDisconnected(ComponentName name) {
			counterService=null;
			Log.i(TAG, "Counter Service Disconnected");
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			counterService=((CounterService.CounterBinder)service).getService();
			Log.i(TAG, "Counter Service Connected");
		}
	};
在Service中创建与Activity打交道的Binder对象:

	//Activity和Service的关联纽带
	public class CounterBinder extends Binder{
		public CounterService getService(){
			return CounterService.this;
		}
	}
	
	private final IBinder binder=new CounterBinder();
	
	//当系统调用bindService时候,该方法会被执行,返回一个自定义的Binder对象给系统
	@Override
	public IBinder onBind(Intent arg0) {
		Log.i(TAG,"Counter Service onBind");
		return binder;
	}

2)注册广播接收者

	//创建一个广播对象,接收从CounterService中发送过来的广播信息,并将相应的信息显示在界面上
	private BroadcastReceiver counterActionReceiver=new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			int counter=intent.getIntExtra(CounterService.COUNTER_VALUE, 0);
			count=counter;
			counterText.setText(count+"");
			Log.i(TAG, "Receive counter event");
		}
	};
	
	@Override
	protected void onResume() {
		super.onResume();
		Log.i(TAG, "MainActivity onResume");
		//注册一个广播接收器,该广播接收器指定了只对CounterService.BROADCAST_COUNTER_ACTION
		//类型的广播感兴趣,当CounterService发送一个广播后sendBroadcast,该广播就会被counterActionReceiver
		//中的onReceive函数接收处理
		//这里是通过代码的形式注册我们的广播,我们也可以在xml中进行相应的注册
		IntentFilter counterActionFilter=new IntentFilter(CounterService.BROADCAST_COUNTER_ACTION);
		registerReceiver(counterActionReceiver, counterActionFilter);
	}

3)点击计数按钮,异步处理逻辑,并时时发送广播:

	public void startCounter(int initVal) {
		//使用异步进行后台计数
		//为什么使用它?因为这个计数的过程我们可以将其类比一个耗时的计算逻辑,耗时的操作则不能在主线程中进行
		//否则会出现ANR(Application not responding)现象
		//也可以使用Handler与线程的结合进行
		AsyncTask<Integer, Integer, Integer> task=new AsyncTask<Integer, Integer, Integer>() {
			@Override
			protected Integer doInBackground(Integer... params) {
				Log.i(TAG, "doInBackground execute");
				Integer initCounter=params[0];
				stop=false;
				while(!stop){
					//调用该方法系统会自动调用onProgressUpdate方法
					publishProgress(initCounter);
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					initCounter++;
				}
				return initCounter;
			}
			
			@Override
			protected void onProgressUpdate(Integer... values) {
				Log.i(TAG, "onProgressUpdate execute");
				super.onProgressUpdate(values);
				int counter=values[0];
				//将时时更新的值广播出去
				Intent intent=new Intent(BROADCAST_COUNTER_ACTION);
				intent.putExtra(COUNTER_VALUE, counter);
				sendBroadcast(intent);
			}
			
			@Override
			protected void onPostExecute(Integer result) {
				Log.i(TAG, "onPostExecute execute");
				int counter=result;
				//将时时更新的值广播出去
				Intent intent=new Intent(BROADCAST_COUNTER_ACTION);
				intent.putExtra(COUNTER_VALUE, counter);
				sendBroadcast(intent);
			}
		};
		task.execute(initVal);
	}

4)广播接收者接收广播,并时时更新界面:
	@Override
		public void onReceive(Context context, Intent intent) {
			int counter=intent.getIntExtra(CounterService.COUNTER_VALUE, 0);
			count=counter;
			counterText.setText(count+"");
			Log.i(TAG, "Receive counter event");
		}
因为AsyncTask的实例化和启动必须在UI线程中,也就是说在主线程中,该程序中,Activity和Service同在主线程中,所以我们能够在Service中实例化和启动AsyncTask!

Android Demo之旅 Activity、Service、BroadCast实现计数统计,布布扣,bubuko.com

Android Demo之旅 Activity、Service、BroadCast实现计数统计

上一篇:Board Wrapping(计算几何求凸包加向量的旋转)


下一篇:AX Dynamic 2012 tabletype:TempDB使用