Android-Service生命周期
2016-01-12 10:18
555 查看
Android-Service生命周期
Service生命周期:———-、
开启服务
当使用startService()开启服务的时候,这样服务就会在后台运行,如果要停止服务的话,必须调用stopService()方法停止服务!
绑定服务
当使用onBind()方法绑定服务的时候,那么就会和该服务建立了通信,如果要解除绑定,要调用unbindService()方法。
这两条路径并不是完全分开的。
即是说,你可以和一个已经调用了 startService()而被开启的service进行绑定。
比如,一个后台音乐service可能因调用 startService()方法而被开启了,稍后,可能用户想要控制播放器或者得到一些当前歌曲的信息,可以通过bindService()将一个activity和service绑定。这种情况下,stopService()或 stopSelf()实际上并不能停止这个service,除非所有的客户都解除绑定。
无论是绑定还是开启服务,都要经过onCreate()这一方法。
还有 如果同时绑定和开启服务,必须要停止服务和解除绑定才可以完全停止运行!
还是实践出真知,写个demo加深自己的理解:
首先是布局:
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/tvOut" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <EditText android:id="@+id/editData" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="默认数据" /> <Button android:id="@+id/btnStartService" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="启动服务" /> <Button android:id="@+id/btnStopService" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="停止服务" /> <Button android:id="@+id/btnBindService" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="绑定服务" /> <Button android:id="@+id/btnUnbindService" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="解除绑定服务" /> </LinearLayout>
四个按钮,分别用于启动服务、停止服务、绑定服务、解除绑定服务。
然后创建一个Service,命名为AgainMyService
1.onCreate()启动服务的时候,首先调用该方法,一旦成功启动服务,那么它只会执行一次
2.onStartCommand()启动服务的时候,调用该方法,然后该方法,调用onStart()方法
3.onDestory()停止服务的时候,调用该方法
如果一个Service又被启动又被绑定,则该Service将会一直在后台运行。并且不管如何调用,onCreate始终只会调用一次,对应startService调用多少次,Service的onStart便会调用多少次。调用unbindService将不会停止Service,而必须调用 stopService 或 Service的 stopSelf 来停止服务。
AgainMyService.java
package com.xieth.as.againconnectservice; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; public class AgainMyService extends Service { private String data; private boolean isrunning = true; public AgainMyService() { } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. Log.d("AgainMyService", "onBind"); throw new UnsupportedOperationException("Not yet implemented"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d("AgainMyService", "onStartCommand"); data = intent.getStringExtra("data"); return super.onStartCommand(intent, flags, startId); } @Override public void onCreate() { super.onCreate(); Log.d("AgainMyService", "onCreate"); new Thread() { @Override public void run() { super.run(); while (isrunning) { try { Log.d("AgainMyService", "data -> " + data); sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } @Override public void onDestroy() { super.onDestroy(); isrunning = false; Log.d("AgainMyService", "onDestory"); } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); Log.d("AgainMyService", "onStart"); } }
AgainMainActivity.java
package com.xieth.as.againconnectservice; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.support.v7.app.AppCompatActivity; import android.view.View; public class AgainMainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection { private Intent it = null; private String data = "这是默认信息"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); it = new Intent(AgainMainActivity.this, AgainMyService.class); findViewById(R.id.btnStartService).setOnClickListener(this); findViewById(R.id.btnStopService).setOnClickListener(this); findViewById(R.id.btnBindService).setOnClickListener(this); findViewById(R.id.btnUnbindService).setOnClickListener(this); } @Override public void onClick(View v) { int id = v.getId(); switch (id) { case R.id.btnStartService: it.putExtra("data", data); startService(it); break; case R.id.btnStopService: stopService(it); break; case R.id.btnBindService: bindService(it, this, Context.BIND_AUTO_CREATE); break; case R.id.btnUnbindService: unbindService(this); break; default: break; } } @Override public void onServiceConnected(ComponentName name, IBinder service) { } @Override public void onServiceDisconnected(ComponentName name) { } }
运行效果:
依次点击启动服务,再次点击启动服务,最后停止服务
输出结果:
首先执行onCreate->onStartCommand->onStart
再次点击执行onStartCommand->onStart,不再执行onCreate,可见此方法执行一次
最后停止服务,执行onDestory方法
接下来就是绑定服务和解除绑定服务:
界面布局一样:
onBind()绑定服务的时候,调用该方法
bindService()其他组件调用Service的onBind()方法。
unbindService()解除绑定时调用该方法
bindService启动模式下的生命周期:在这种模式下,当调用者首次使用bindService绑定一个服务时,系统会实例化一个Service实例,并一次调用其onCreate方法和onBind方法,然后调用者就可以和服务进行交互了,此后,如果再次使用bindService绑定服务,系统不会创建新的Service实例,也不会再调用onBind方法;如果我们需要解除与这个服务的绑定,可使用unbindService方法,此时onUnbind方法和onDestroy方法会被调用。
demo:
修改一下AgainMyService.java
@Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. data = intent.getStringExtra("data"); Log.d("AgainMyService", "onBind"); return new Binder(); }
AgainMainActivity.java
@Override public void onServiceConnected(ComponentName name, IBinder service) { Log.d("AgainMyService", "onServiceConnected"); } @Override public void onServiceDisconnected(ComponentName name) { Log.d("AgainMyService", "onServiceDisconnected"); }
依次点击绑定服务和解除绑定服务:
输出结果:
执行顺序onCreate->onBind->onServiceConnected->onDestory
在使用bindService绑定服务时,我们需要一个ServiceConnection代表与服务的连接,它只有两个方法,onServiceConnected和onServiceDisconnected,前者是在操作者在连接一个服务成功时被调用,而后者是在服务崩溃或被杀死导致的连接中断时被调用,而如果我们自己解除绑定时则不会被调用。
2016年1月12日10:18:22 记录
相关文章推荐
- android开发 防止输入键盘挡住界面
- Android的Window类
- Android 全屏沉浸模式(支持API 19及以上系统)
- android 三级缓存
- android 开发文档(sdk)中docs不能搜索
- android代码混淆和打包签名
- Android dimen
- android用户界面之一
- 实例详解Android文件存储数据方式
- 如何使用Android最新的RecyclerView取代ListView?
- Android内存泄漏终极解决篇(下)
- Android开发组件
- Android实战技巧:深入解析AsyncTask
- Android中使用NDK环境开发JNI程序例子
- Android事件散发机制
- Android 在Fragment中使用TabLayout时标题不显示问题
- 如何使用Android最新的RecyclerView取代ListView?
- Android 对话框(Dialog)大全 建立你自己的对话框
- Android图片加载与缓存开源框架:Android Glide
- 基于开源框架Glide加载Gif资源图到Android ImageView中