android四大组件service
2015-11-10 22:48
447 查看
1、Service与Activity
service与activity都是android的基本组件,并且都是Context的子类,可以把service当作是没有界面的activity。与activity一样,不能在主线程中作耗时操作。都必须在清单文件中配置。2、Service两种启动服务的方式和不同。
对于为什么会有两咱启动方式,他们是合适不同的场景的。使用startService启动的服务,它不会随着启动它的组件生命周期结束而结束,只要不调用停止服务或者手机结束进程,服务将一直处于运行中。而通过bindStart()启动的服务是与启动它的组件生命周期相关联。如果启动它的组件销毁了,那么通过启动它的服务也就销毁了。
1. StartService()的生命周期:
onCreate()——如果服务已经创建,则不会再走onCreate()方法。onStartCommand—-每一次调用都会执行:
当其它组件,比如一个activity,通过调用startService()请求started方式的服务时,系统将会调用本方法。 一旦本方法执行,服务就被启动,并在后台一直运行下去。 如果你的代码实现了本方法,你就有责任在完成工作后通过调用stopSelf()或stopService()终止服务。 (如果你只想提供bind方式,那就不需要实现本方法。)
onStart()——每一次调用都会执行
onDesotry()——如果不调用.stopService()或者调用Service.stopSelfResult(),service将一直处于开启的状态;
这类服务由其它组件调用startService()来创建。然后保持运行,且必须通过调用stopSelf()自行终止。其它组件也可通过调用stopService() 终止这类服务。服务终止后,系统会把它销毁。
2、 通过bindService()的方式启动启动服务
当其它组件需要通过bindService()绑定服务时(比如执行RPC),系统会调用本方法。 在本方法的实现代码中,你必须返回IBinder来提供一个接口,客户端用它来和服务进行通信。 你必须确保实现本方法,不过假如你不需要提供绑定,那就返回null即可。bindService()— 调用
onCreate()—–首先会走onCreate()方法
onBind()——-绑定服务
Service running—–服务正在运行中
onUnbind()——-解除绑定
onDesotry()——销毁服务
服务由其它组件(客户端)调用bindService()来创建。然后客户端通过一个IBinder接口与服务进行通信。客户端可以通过调用unbindService()来关闭联接。多个客户端可以绑定到同一个服务上,当所有的客户端都解除绑定后,系统会销毁服务。(服务不需要自行终止。)
3、对于两种启动方式的混合启动。
通过startService()方式启动服务,服务就可以做到长驻内存中(不依赖于组件)。使用bindService()的方式启动服务,服务与绑定组件相依存,并且通过bind的方式可以与service进行很多的交互,在conn中可以获取服务中的信息:比如说连接的状态,如果有下载任务,还可以得到下载的进度,情况等。但是有时候用过这两种服务的混合开启这种情况使用的也比较多,比如说音乐播放器必须运行在服务中,但又需要被前台activity调用这就要用混合服务的方式启动了。
先startService(),再bindService(),销毁时先unbindService(),再stopService()。
4 、IntentService
intentService可能使用的人比较少,甚至很多人都没听过。但intentService是非常好用和适用的。利用继承Service写的服务通过startService()启动服务,这种服务一旦启动,就处于运行状态,如果想要在线程执行后停止服务,只能调用 stopSelf()的方法。
为了方便起见,也是减少一些可能发生的错误,比如说经常忘记开启,或者调用stopSelf()的方法。Android中提供了一个IntentService()类,这个类可以简单的创建一个异步的,会自动停止的服务。
IntentService的执行步骤:
创建一个子线程,并且执行onStartCommand()中收到的intent。
创建一个工作队列,每次向onHandleIntent()传入一个intent,
处理完所有的请求后,自动调用stopSelf()停止服务。
详见实例3
5、Service与Activity之间的通信和传递数据;
1、activity向service发送数据比较简单,与activity之间传递数据一样。Intent intent =new Intent(this,MyService.class);
intent.putExtra(“name”,”yu”);
startService(intent);
String name=intent.getStringExtra(“name”);
Log.i(TAG,name);
2、service向activity传递数据或者更新UI
如果需要数据持久化:
1、在service得到网络数据保存到sp中数据,在activity中从sp中取出数据更新UI;
2、在service中得到网络数据保存到数据库中,在activity中查询数据库,并更新UI
如果不需要持久化:
3、能过BroadcastReceiver把service中的数据传递给activity,
4、如果服务通过bindService的方式启动,还可以通过onBind()方法来传递数据给activity
6、如何用Service开启一个长期运行,定时更新的任务。比如天气,或者新闻每隔三小时更新;
在activity中启动服务。在服务中的onStartCommand中开启子线程,连网得到网络数据,并且调用AlermManager定时,用PendingIntent得到广播,并发送给广播。
在广播的onReceive()中再次启动服务,这样就形成了一个长期的在后台运行,并且定时刷新的服务。
详细实例4
1、通过startService启动服务代码:
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startService(new Intent(MainActivity.this,MyStartService.class)); } }
在MyStartService()中的代码:
public class MyStartService extends Service { private static final String TAG="MyStartService"; //如果服务已经开启了,调用将不会再走onCreate()的方法 @Override public void onCreate() { super.onCreate(); Log.i(TAG,"service onCreate()"); } //每一次调用都是执行onStartCommand代码,在这段代码中主要做onStart()方法前的一些工作 @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG,"service onStartCommend()"); return super.onStartCommand(intent, flags, startId); } //onStart方法是在onStartCommand执行后走的方法。 @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); Log.i(TAG, "service onStart()"); } //销毁服务; @Override public void onDestroy() { super.onDestroy(); Log.i(TAG, "service onDestory()"); } @Override public IBinder onBind(Intent intent) { return null; } }
运行结果:第一次走了onCreate()的方法,再次则没有走onCreate()
public class MyBindService extends Service { private static final String TAG = "MyBindService"; //创建服务; @Override public void onCreate() { Log.i(TAG, "service onCreate()"); super.onCreate(); } //绑定服务,在绑定的服务中返回一个Bind对象; @Override public IBinder onBind(Intent intent) { Log.i(TAG, "service onBind()"); return mBinder; } //销毁服务 @Override public void onDestroy() { Log.i(TAG, "service onDestory()"); super.onDestroy(); } private MyBinder mBinder = new MyBinder(); //创建MyBinder,继承Binder,调用bind启动服务时,把MyBindService返回 public class MyBinder extends Binder { public MyBindService getService() { return MyBindService.this; } } }
在Activity中调用:注意!通过绑定的服务会随着组件的结束而结束,在onDestory()中调用解除绑定代码
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //通过startService()的方式启动服务; // startService(new Intent(MainActivity.this,MyStartService.class)); //通过bindService()的方式启动服务; Intent intent = new Intent(MainActivity.this, MyBindService.class); bindService(intent, conn, BIND_AUTO_CREATE); } ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onDestroy() { unbindService(conn); super.onDestroy(); } }
效果图:当Activity执行了onDestory()时,服务也就销毁了
3、 intentService实例:
public class HelloIntentService extends IntentService { /** * 构造方法是必需的,必须用工作线程名称作为参数 * 调用父类的[http://developer.android.com/reference/android/app/IntentService.html#IntentService(java.lang.String) IntentService(String)]构造方法。 */ public HelloIntentService() { super("HelloIntentService"); } /** * IntentService从缺省的工作线程中调用本方法,并用启动服务的intent作为参数。 * 本方法返回后,IntentService将适时终止这个服务。 */ @Override protected void onHandleIntent(Intent intent) { // 通常我们会在这里执行一些工作,比如下载文件。 // 作为例子,我们只是睡5秒钟。 long endTime = System.currentTimeMillis() + 5*1000; while (System.currentTimeMillis() < endTime) { synchronized (this) { try { wait(endTime - System.currentTimeMillis()); } catch (Exception e) { } } } } }
继承IntentService后,增加了一个构造方法和一个onHandleIntent()方法的实现。
还可以加上其他方法,比如onCreate()、onStartCommand()、onDestroy(), 请确保调用一下父类的实现代码,以便IntentService能正确处理工作线程的生命周期。
实例4、在后台定时数据更新为例,比如说每隔三小时天气更新。
在activity中代码:
/** * 如何做一个定时的,在后台运行的长期任务,比如天气,或者新闻每小时更新? * * 在activity中启动了service,然后在service中每隔10秒中启动广播,这样onReceive()方法得到执行, 在广播中再次开启service,这样就形成一个永久的循环,一个长期的在后台运行的任务也就启动起来。 */ public class MainActivity extends Activity { private TextView tv_time; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_time= (TextView) findViewById(R.id.tv_time); Intent intent=new Intent(this,AutoService.class); startService(intent); } }
在AutoService中代码:
public class AutoService extends Service { private static final String TAG="AutoService"; private String str_time=""; //不需要绑定 @Override public IBinder onBind(Intent intent) { return null; } //onStartCommand在onStart()方法前运行; @Override public int onStartCommand(Intent intent, int flags, int startId) { new Thread(new Runnable() { @Override public void run() { //开启子线程,在这里做耗时操作;比如说获取天气信息; Log.i(TAG, getTime()); } }).start(); AlarmManager manager= (AlarmManager) getSystemService(ALARM_SERVICE); int time=10*1000; long triggerAtTIME= SystemClock.elapsedRealtime()+time; Intent i=new Intent(this,AutoBroadcastReceiver.class); PendingIntent pi=PendingIntent.getBroadcast(this,0,i,0); manager.set(AlarmManager.ELAPSED_REALTIME, triggerAtTIME, pi); return super.onStartCommand(intent, flags, startId); } public String getTime(){ SimpleDateFormat sdf =new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss "); Date date=new Date(System.currentTimeMillis()); String str=sdf.format(date); return str; } }
在AutoBroadcastReceiver中代码:
public class AutoBroadcastReceiver extends BroadcastReceiver { public static final String TAG="AutoBroadcaseReceiver"; @Override public void onReceive(Context context, Intent intent) { Intent i = new Intent(context, AutoService.class); context.startService(i); } }
相关文章推荐
- Android数据库使用(LitePal)
- Android学习之动态调用碎片
- Android Studio 简单设置
- android的启动模式 到底在什么时候用呢?
- Android使用兰贝壳儿实现多渠道打包
- Android主页面 多层Fragment嵌套(Fragment+ViewPager)滑动
- 使用javah生成.h文件, 出现无法访问android.app,Activity的错误的解决
- Android 学习笔记之AndBase框架学习(五) 数据库ORM..注解,数据库对象映射...
- 如何手动销毁surfaceview 并重建
- Android项目Tab类型主界面大总结 Fragment+TabPageIndicator+ViewPager
- Android 图片轮播控件
- Android自定义控件——手把手教你实现SlidingMenu(二)
- Android NDK 如何缩减库的大小
- Android中对Log日志文件的分析
- android91 代码注册广播接收者
- Android数据存储五种方式总结
- Android Studio 汉字转拼音
- Android四大组件之内容提供器
- Android兼容性问题 -- 设置圆角背景方向相反问题
- Android通过编译源代码提供系统服务