您的位置:首页 > 移动开发 > Android开发

Android-Service生命周期

2016-01-12 10:18 483 查看

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 记录
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: