Android Service
##Service
啥也不说直接上代码
public class AppService extends Service
{
private static final String TAG = "ExampleService";
private final AppBinder mAppBinder = new AppService.AppBinder();
@Override
public IBinder onBind(Intent intent)
{
return mAppBinder;
}
@Override
public void onCreate()
{
Log.i(TAG, "ExampleService.onCreate()");
super.onCreate();
}
@Override
public void onStart(Intent intent, int startId)
{
Log.i(TAG, "ExampleService.onStart()");
super.onStart(intent, startId);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.i(TAG, "ExampleService.onStartCommand()");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy()
{
Log.i(TAG, "ExampleService.onDestroy()");
super.onDestroy();
}
public class AppBinder extends Binder
{
AppService getService()
{
return AppService.this;
}
}
}
上面代码片段是一个Service,在生命周期位置标记了一下,既然Service已经生成好了,下面看一下如何使用
##使用Service
###startService,stopService
public class MainActivity extends ActionBarActivity
{
private BroadcastReceiver mReceive;
private final static String RECEIVE_KEY = "MY_RECEIVE_KEY";
private final Intent mServiceIntent = new Intent(MainActivity.this, AppService.class);
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initContentView();
mReceive = new MyReceive(mServiceIntent);
IntentFilter filter = new IntentFilter();
filter.addAction(RECEIVE_KEY);
registerReceiver(mReceive, filter);
}
private static class MyReceive extends BroadcastReceiver
{
private Intent it;
MyReceive(Intent it)
{
this.it = it;
}
@Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equalsIgnoreCase(RECEIVE_KEY))
{
context.startService(it);
}
}
}
@Override
protected void onDestroy()
{
super.onDestroy();
if (mReceive != null)
{
try
{
unregisterReceiver(mReceive);
}
catch (Exception e)
{
e.printStackTrace();
}
mReceive = null;
}
stopService(mServiceIntent);
}
private void initContentView()
{
final View textView = findViewById(R.id.main_activity_text_view);
if (textView != null)
{
textView.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
Intent itReceive = new Intent(RECEIVE_KEY);
sendBroadcast(itReceive);
}
});
}
}
}
###bindService,unbindService
public class MainActivity extends ActionBarActivity
{
private static AppServiceConnection SC = new AppServiceConnection();
private static class AppServiceConnection implements ServiceConnection
{
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
AppService s = ((AppService.AppBinder) service).getService();
//TODO
}
@Override
public void onServiceDisconnected(ComponentName name)
{
//TO show a message to custom;
}
}
private static class MyReceive extends BroadcastReceiver
{
private Intent it;
MyReceive(Intent it)
{
this.it = it;
}
@Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equalsIgnoreCase(RECEIVE_KEY))
{
context.bindService(it, SC, Context.BIND_AUTO_CREATE);
}
}
}
@Override
protected void onDestroy()
{
super.onDestroy();
if (SC != null)
{
unbindService(SC);
SC = null;
}
}
}
##配置Manifest
<service
android:name="studio.neulion.com.tasktest.AppService" />
##运行
如果我们使用第一种方式startService,而在Activity的时候没有主动stopService,当我们退出App的时候会怎样?
Service还在运行
然后回到我们的Activity,再次点击启动Service,控制台输出日志如下:
onCreate()方法没有被调用,说明它并没有重新被创建。
然后我们修改一下代码,在onDestory方法中添加stopService,再退出后输出日志如下:
##小结
startService()与bindService()区别:
- started service(启动服务)是由其他组件调用startService()方法启动的,这导致服务的onStartCommand()方法被调用。当服务是started状态时,其生命周期与启动它的组件无关,并且可以在后台无限期运行,即使启动服务的组件已经被销毁。因此,服务需要在完成任务后调用stopSelf()方法停止,或者由其他组件调用stopService()方法停止。
- 使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。
另外说一下:开发人员需要在应用程序配置文件中声明全部的service,使用标签。
多说一句,对于Android的四大组件:
四大基本组件都需要注册才能使用,每个Activity、service、Content Provider都需要在AndroidManifest文件中进行配置。AndroidManifest文件中未进行声明的activity、服务以及内容提供者将不为系统所见,从而也就不可用。而broadcast receiver广播接收者的注册分静态注册(在AndroidManifest文件中进行配置)和通过代码动态创建并以调用Context.registerReceiver()的方式注册至系统。需要注意的是在AndroidManifest文件中进行配置的广播接收者会随系统的启动而一直处于活跃状态,只要接收到感兴趣的广播就会触发(即使程序未运行)。
最后说一下bindService
需要的参数flag
含义:
-
START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
-
START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统将会把它置为started状态,系统不会自动重启该服务,直到startService(Intent intent)方法再次被调用;。
-
START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
-
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
3: http://yzl.terncloud.com/linux1s1s20150503170802: https://i-blog.csdnimg.cn/blog_migrate/8bd943fc575ac59d2f3036efdcff1ad2.png