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

来源:互联网 发布:金蝶软件资产负债表 编辑:程序博客网 时间:2024/06/07 03:37

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

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

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

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

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


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

实现功能:


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

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() {    @Overridepublic void onServiceDisconnected(ComponentName name) {counterService=null;Log.i(TAG, "Counter Service Disconnected");}@Overridepublic 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对象给系统@Overridepublic IBinder onBind(Intent arg0) {Log.i(TAG,"Counter Service onBind");return binder;}

2)注册广播接收者

//创建一个广播对象,接收从CounterService中发送过来的广播信息,并将相应的信息显示在界面上private BroadcastReceiver counterActionReceiver=new BroadcastReceiver() {@Overridepublic 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");}};@Overrideprotected 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>() {@Overrideprotected 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;}@Overrideprotected 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);}@Overrideprotected 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)广播接收者接收广播,并时时更新界面:
@Overridepublic 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!

3 0