时间匆匆,转眼就是大半个月过去了,学习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() { @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