一、概述
1.Service是Android
四大组件之一,和Activity的级别相当 2.Service是可以
长时间运行在后台的,是
不可见,是
没有界面的组件 3.Service是
运行在主线程中的 4.Service可以
跨进程调用
不过需要注意的是,服务并不是运行在一个独立的进程当中的,而是依赖于创建服务时所在的应用程序进程。当某个应用程序进程被杀掉时,所有依赖于该进程的服务也会停止运行。
定义一个服务
public class MyService1 extends Service {
public MyService1() {
}
//这个方法是Service中唯一的一个抽象方法,所以必须要在子类里实现
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
//创建服务的时候调用
@Override
public void onCreate() {
super.onCreate();
}
//在每次服务启动的时候调用
// 如果我们希望服务一旦启动就立刻去执行某个动作,就可以将逻辑写在onStartCommand()方法里
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
//会在服务销毁的时候调用
@Override
public void onDestroy() {
super.onDestroy();
}
}
startService
1.新建类继承Service
2.重写 onCreate方法(Service在创建时调用的方法,可以用来做数据初始化,Service在没有停止之前,只会执行一次)
3.实现Onbind抽象方法(由于Service是一个抽象类,定义了一个onBind抽象方法,所以必须实现此抽象方法,return null即可,此方法在startService方式用不上,无需理会即可)
4.重写OnStartCommand方法(Service创建后会调用OnStartCommand ,此方法中可以接受调用者传递过来的参数,并且可以编写需要的逻辑代码,当重复调用Service时,OnStartCommand 会重复执行,onStart方法已弃用)
5.重写onDestroy方法(Service在退出时调用,此方法可以编写释放资源的操作)
6.在Androidmanifest中注册service
7.在有Context环境中通过startService启动Service
8.在有Context环境中通过stopService停止Service
代码实现:1.定义一个启动服务和停止服务的布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.lk.servicetest.MainActivity">
<Button
android:id="@+id/start_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start Service"
android:textAllCaps="false" />
<Button
android:id="@+id/stop_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Stop Service"
android:textAllCaps="false" />
</LinearLayout>
2.然后修改MainActivity中的代码
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button startService = (Button) findViewById(R.id.start_service);
Button stopService = (Button) findViewById(R.id.stop_service);
startService.setOnClickListener(this);
stopService.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.start_service:
Intent startIntent = new Intent(this, MyService.class);
startService(startIntent);//启动服务
break;
case R.id.stop_service:
Intent stopIntent = new Intent(this, MyService.class);
stopService(stopIntent);//停止服务
break;
default:
break;
}
}
}
bindService
但上面的startService和stopService,虽然服务是在活动里启动的,但是启动了服务之后,活动和服务基本就没有什么联系了,要想活动和服务的关系更紧密一些,我们就需要使用onBind()方法。
我们以一个下载功能的实例来学习bindService,实现这个功能的思路是创建一个专门的Binder对象来对下载功能进行管理。
1.修改MyService中的代码
public class MyService extends Service {
//新建一个DownloadBinder类,并让他继承自Binder,然后在它的内部提供了开始下载以及查看下载进度的方法。
// 这只是两个模拟方法,并没有实现真正的功能,并在这两个方法中分别打印一行日志
//接着,在MyService中创建了DownloadBinder的实例,然后在onBind()方法里返回了这个实例,这样MyService中的工作就全部完成了
private DownloadBinder mbinder = new DownloadBinder();
class DownloadBinder extends Binder {
public void startDownload() {
Log.d("MyService", "startDownload executed");
}
public int getProgress() {
Log.d("MyService", "getProgress executed");
return 0;
}
}
public MyService() {
}
//这个方法是Service中唯一的一个抽象方法,所以必须要在子类里实现
@Override
public IBinder onBind(Intent intent) {
return mbinder;
}
//会在服务创建的时候调用
@Override
public void onCreate() {
super.onCreate();
Log.d("MyService", "onCreate executed");
}
//会在每次服务启动的时候调用。
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("MyService", "onStartCommand executed");
return super.onStartCommand(intent, flags, startId);
}
//会在服务销毁的时候调用
@Override
public void onDestroy() {
super.onDestroy();
Log.d("MyService", "onDestroy executed");
}
}
2.定义布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.lk.servicetest.MainActivity"> <Button android:id="@+id/bind_service" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Bind Service" android:textAllCaps="false" /> <Button android:id="@+id/unbind_service" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Unbind Service" android:textAllCaps="false" /> </LinearLayout>
3.修改MainActivity中的代码
public class MainActivity extends AppCompatActivity implements View.OnClickListener { //在这里我们首先创建了一个ServiceConnection的匿名类,在里面重写了onServiceConnected()方法和onServiceDisconnected()方法, // 这两个方法分别会在活动与服务成功绑定以及活动与服务的连接断开的时候调用 private MyService.DownloadBinder downloadBinder; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { downloadBinder = (MyService.DownloadBinder) service; downloadBinder.startDownload(); downloadBinder.getProgress(); } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button bindService = (Button) findViewById(R.id.bind_service); Button unBindService = (Button) findViewById(R.id.unbind_service); bindService.setOnClickListener(this); unBindService.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.bind_service: Intent bindIntent = new Intent(this, MyService.class); bindService(bindIntent, connection, BIND_AUTO_CREATE);//绑定服务 break; case R.id.unbind_service: unbindService(connection);//解绑服务 break; default: break; } } }
下一篇博客写关于服务的生命周期和IntentService