Service 是安卓的四大组件之一 , 用于长时间驻留在后台进行操作
注意:它区别于线程,虽然是在app中进行创建和邦定的,但是最终是在主线程里运行的
所以,一些耗时的操作,例如:网络请求。用户输入,音频播放等,最好是在Service的子线程中进行处理
Service有两种启动方式:context.startservice 和 context.bindservice
1:context.startservice的生命周期:
context.startService() ->onCreate()- >onStart()(可多次调用)->Service running –>context.stopService() | ->onDestroy() ->Service stop
如果在程序运行期间,有调用了 startService(),那么这个时候就不走onCreate()方法,而是直接走onStart()方法。所以一个Service的onStart方法可能会重复调用多次
stopService的时候直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。该Service的调用者再启动起来后可以通过stopService关闭Service。
2:context.bindservice的生命周期:
context.bindService()->onCreate()->onBind()(只一次,不可多次绑定)->Service running –>onUnbind() -> onDestroy() ->Service stop
onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind->onDestroy相应退出。
总结:
1:在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次
2:使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。*
采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。
3:使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止
采用Context.bindService()方法启动服务时只能调用onUnbind()方法解除调用者与服务解除,服务结束时会调用onDestroy()方法。
代码:
1: 用startservice()启动service:
第一步:创建一个类继承自 Service。里面有生命周期的所有方法。
第二步:Service是android的四大组件之一,所以需要在 AndroidManifest.xml文件中注册。
第三步:在mainactivity中通过startService(intent)方法启动Service。 intent是指定要启动的service。
2:用bindService()启动Service:
第一步: 创建一个类继承自Service。里面有生命周期的所有方法。
第二步:Service是android的四大组件之一,所以需要在 AndroidManifest.xml文件中注册。
第三步:在创建的类里面创建个内部类,用于给onBind方法传值。使得onBind方法拿到返回值。(是用来传数据的。)
第四步;再通过bindService()里面的第二参数访问者(activity 或 客户)与service进行连接。
bindService()里面有三个参数:
参数1;通过intent指定要启动的service
参数2;是ServiceConnected的对象,如果与sercive连接成功,会调用ServiceConnected对象里的onServiceConnected()的方法。而onServiceConnected()方法中有一个Ibind对象,它使得activity与Service之间进行通信。而onBind()方法返回的Ibind与Ibind是同一个值,这样activity就与内部类传的数据联系起来了,其实也就是与Service进行了连接通信。
Mainactivity中:
package com.coderqi.android2lesson_15_service;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
/**
*
*
* Service生命周期
* Service有两种启动方式:1:startService 2 :BindService
* 第一种生命周期为:onCreate()---> onStart() --> ServiceRunning() -->
* (如果调用context.stopService()) ---> onDestory --> ServiceShutdown
* 如果在程序运行期间,有调用了 startService(),那么这个时候就不走onCreate()方法,而是直接走onStart()方法。
*
* 第二种生命周期:onCreate()---> onBind() --> ServiceRunning() -->
* onUnbind()--> onDestory --> ServiceShutdown
* 和上面一样,如果运行期间调用了 BindService(),那么这个时候就会走onBind()方法,而不走onCrevice()方法。
*
*
* 区别:onBing将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态和其他操作,
* 这个时候调用者和Service是绑定在一起的,Context退出了。Service就会调用onUnbind()-->ondestory()进行退出。
* 也就是说BindService()会把service和activity进行绑定,一旦activity销毁,那么对应的服务也就销毁了。
* 但是按home键不会消失。
*
* @param savedInstanceState
*/
private Button startButton;
private Button stopButton;
private Button bindButon;
private Button unbindButon;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startButton = (Button) findViewById(R.id.start_service);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//调用方法进行启动服务
startService(new Intent(MyService.ACTION));
}
});
stopButton= (Button) findViewById(R.id.stop_service);
stopButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
stopService(new Intent(MyService.ACTION));
}
});
bindButon= (Button) findViewById(R.id.bind_service);
bindButon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//调用方法绑定服务
Intent intent= new Intent(MyService.ACTION);
bindService(intent,sc,BIND_AUTO_CREATE);
}
});
unbindButon= (Button) findViewById(R.id.unbind_service);
unbindButon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
unbindService(sc);
}
});
}
ServiceConnection sc = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.i("输出","context与服务绑定成功");
MyService.SimpleBind binder = (MyService.SimpleBind) iBinder;
Log.i("输出","从服务中户区数据为:"+ binder.getString());
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.i("输出","context与服务解绑成功");
}
};
}
创建的类:
package com.coderqi.android2lesson_15_service;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
/**
* Created by user on 2016/7/22.
*/
public class MyService extends Service {
final static String ACTION = "com.coderqi.serviceDemo";
private SimpleBind binder;
@Override
public void onCreate() {
super.onCreate();
Log.i("周期","onCreate");
binder = new SimpleBind();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("周期","onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i("周期","onDestory");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.i("输出","onbind");
return binder;
}
@Override
public boolean onUnbind(Intent intent) {
Log.i("输出","onunbind");
return super.onUnbind(intent);
}
class SimpleBind extends Binder {
//这里面的方法就是自定义的方法,用来实现服务的逻辑思维的
//模拟从服务中获取数据
public String getString(){
return "你获取数据一个,来自服务";
}
//提供了两个方法进行音乐的控制,一个是播放 ,一个是暂停 ,下一首
}
}
注册:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.coderqi.android2lesson_15_service">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyService">
<!--这个是进行服务启动时候的过滤的,启动指定的服务-->
<intent-filter>
<action android:name="com.coderqi.serviceDemo"/>
</intent-filter>
</service>
</application>
</manifest>