service根据启动方式的不一样,走的生命周期也不一样,下面我们看一张两种方式启动service的service的生命周期:
布局文件
<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:gravity="center" android:orientation="vertical" >
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal">
<Button android:id="@+id/btn_start" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:padding="30dp" android:text="startService" />
<Button android:id="@+id/btn_end" android:layout_width="0dp" android:padding="30dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="stopService" />
</LinearLayout>
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal">
<Button android:id="@+id/btn_bind" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:padding="30dp" android:text="bindService" />
<Button android:id="@+id/btn_unbind" android:layout_width="0dp" android:padding="30dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="unbindService" />
</LinearLayout>
</LinearLayout>
CommonService.java
package com.example.servicedemo;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class CommonService extends Service {
@Override
public IBinder onBind(Intent arg0) {
Log.e("onBind", "===============onBind================");
return null;
}
@Override
public void onCreate() {
Log.e("onCreate", "===============onCreate================");
super.onCreate();
}
@Override
public void onDestroy() {
Log.e("onDestroy", "===============onDestroy================");
super.onDestroy();
}
@Override
public void onRebind(Intent intent) {
Log.e("onRebind", "===============onRebind================");
super.onRebind(intent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("onStartCommand", "===============onStartCommand================");
return super.onStartCommand(intent, flags, startId);
}
@Override
public boolean onUnbind(Intent intent) {
Log.e("onUnbind", "===============onUnbind================");
return super.onUnbind(intent);
}
}
MainActivity.java
package com.example.servicedemo;
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity implements View.OnClickListener{
private ServiceConnection conn = new ServiceConnection() {
/** * 当前客户端与服务断开连接的时候回调,在这里客户端就是MainActivity * @param name */
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e("onServiceDisconnected", "=======断开连接========");
}
/** * 当客户端与Service连接成功的时候回调,在这里客户端就是MainActivity * @param name * @param service */
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.e("onServiceConnected", "=======连接成功========");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn_start = (Button) findViewById(R.id.btn_start);
btn_start.setOnClickListener(this);
Button btn_bind = (Button) findViewById(R.id.btn_bind);
btn_bind.setOnClickListener(this);
Button btn_end = (Button) findViewById(R.id.btn_end);
btn_end.setOnClickListener(this);
Button btn_unbind = (Button) findViewById(R.id.btn_unbind);
btn_unbind.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Intent intent;
switch (v.getId()) {
case R.id.btn_start:
intent = new Intent(this,CommonService.class);
startService(intent);
break;
case R.id.btn_bind:
intent = new Intent(this,CommonService.class);
bindService(intent, conn, Service.BIND_AUTO_CREATE);
break;
case R.id.btn_end:
intent = new Intent(this,CommonService.class);
stopService(intent);
break;
case R.id.btn_unbind:
unbindService(conn);
break;
}
}
}
<service android:name="com.example.servicedemo.CommonService"></service>
从上面我们可以看出多次启动一个已有的service只会调用一个onCreate,但每次都会调用onStartCommand方法。下面我们看看bindService和unbindService:
连点5次bindService按钮:
我们看到,无论我们调用几次bindService,onCreate和onBind只会调用一次
IntentService是Service类的子类,用来处理异步请求。客户端可以通过startService(Intent)方法传递请求给IntentService。IntentService在onCreate()函数中通过HandlerThread单独开启一个线程来处理所有Intent请求对象(通过startService的方式发送过来的)所对应的任务,这样以免事务处理阻塞主线程。执行完上一个Intent请求对象所对应的工作之后,如果没有新的Intent请求达到,则自动停止Service;否则执行下一个Intent请求所对应的任务。
IntentService在处理事务时,还是采用的Handler方式,创建一个名叫ServiceHandler的内部Handler,并把它直接绑定到HandlerThread所对应的子线程。 ServiceHandler把处理一个intent所对应的事务都封装到叫做onHandleIntent的虚函数;因此我们直接实现虚函数onHandleIntent,再在里面根据Intent的不同进行不同的事务处理就可以了。
另外,IntentService默认实现了Onbind()方法,返回值为null。
使用IntentService需要两个步骤:
1、写构造函数
2、实现虚函数onHandleIntent,并在里面根据Intent的不同进行不同的事务处理就可以了。
好处:处理异步请求的时候可以减少写代码的工作量,比较轻松地实现项目的需求
注意:IntentService的构造函数一定是参数为空的构造函数(不然会报无空参数的构造方法初始化异常),然后再在其中调用super(“name”)这种形式的构造函数,那个name是写给我们程序员看的,没有什么实际意义。我们只要给他一个字符串就行了,通常我们会把它的名字作为参数传进去