Android service初学

本文详细介绍了Android中的Service组件,包括其作用、启动方式及与线程的关系。通过具体示例讲解了如何使用startService()和bindService()两种方法启动Service。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Service作为Android四大组件之一,在每一个应用程序中都扮演着非常重要的角色。它主要用于在后台处理一些耗时的逻辑,或者去执行某些需要长期运行的任务。必要的时候我们甚至可以在程序退出的情况下,让Service在后台继续保持运行状态。


Service的启动方法

一、通过startService()方法

  1.创建一个MyService类来继承Service并重写父类的onCreate()onStartCommand()onDestroy()方法

public class Myservice extends Service {

public static final String TAG="Myservice";

public void onCreate(){

super.onCreate();

Log.i(TAG"Service onCreate");

}

public int onStartCommand(Intent intent,int flags,int startId){

Log.i(TAG"Service onStartCommand");

return super.onStartCommand(intent, flags, startId);

}

public void onDestory(){

Log.i(TAG"Service onDestory");

super.onDestroy();

}

@Override

public IBinder onBind(Intent intent) {

return null;

}

 

}

2.设置布局文件和MainActivity,如下图所示

 MainActivity代码


布局文件代码


另外需要注意,项目中的每一个Service都必须在AndroidManifest.xml中注册才行,所以还需要编辑AndroidManifest.xml文件,代码如下所示:


当点击Start Service按钮时,可以看到打印的Log日志如下:


也就是说,当启动一个Service的时候,会调用该Service中的onCreate()onStartCommand()方法。onStartCommand()方法中写需要执行的功能代码。

如果当前Service已经被创建过了,不管怎样调用startService()方法,onCreate()方法都不会再执行。因此你可以再多点击几次Start Service按钮试一次,每次都只会有onStartCommand()方法中的打印日志。如下所示:


我们还可以到手机的应用程序管理界面来检查一下MyService是不是正在运行,如下图所示:


二.通过bindService()方法启动

1.创建一个BinderService类来继承Service,并创建一个MyBinder内部类来扩展Binder

public class BinderService extends Service{

private static final String TAG="BinderService";

    //创建一个Binder实例

private MyBinder binder=new MyBinder();

   

     //创建一个类来扩展Binder

public class MyBinder extends Binder{

           //返回当前Service的方法

public BinderService getService(){

return BinderService.this;

}

}

@Override

public IBinder onBind(Intent intent) {

//返回对象

return binder

}

      //定义自己需要实现的方法

public void Mymethod(){

Log.i(TAG"BinderService is running"); 

Toast.makeText(this"绑定Service成功", Toast.LENGTH_SHORT).show();

}

public void onCreate(){

super.onCreate();

Log.i(TAG"Service onCreate");

}

public int onStartCommand(Intent intent,int flags,int starId){

Log.i(TAG"Service onStartCommand");

return START_NOT_STICKY;

}

public void onDestroy(){

super.onDestroy();

Log.i(TAG"Service onDestroy");

}

 

}

2.在java中的代码

public class MainActivity extends Activity implements OnClickListener{

private Button bindService;

private Button unbindService;

//设置一个标记检查是否绑定

private Boolean isConnected=false;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

bindService=(Button)findViewById(R.id.bindService);

unbindService=(Button)findViewById(R.id.unbindService);

bindService.setOnClickListener(this);

unbindService.setOnClickListener(this);

}

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.bindService:

Intent intent=new Intent(this,BinderService.class);

bindService(intent, connectionBIND_AUTO_CREATE);

break;

case R.id.unbindService:

if(isConnected){

unbindService(connection);

}

 

default:

break;

}

}

    //实现获得Binder实例方法

private ServiceConnection connection=new ServiceConnection(){

 

public void onServiceConnected(ComponentName name, IBinder service) {

  //通过Binder对象获取service对象,注意与Binderservice中创建的对象不能同名。

MyBinder myBinder=(MyBinder)service;

   //通过service对象来获取service中的服务和方法

BinderService bindservice=myBinder.getService();

bindservice.Mymethod();

    isConnected=true;

}

 

@Override

public void onServiceDisconnected(ComponentName name) {

isConnected=false;

}

};

 

}

由于Android 中的Service使用了onBind 的方法去绑定服务,返回一个Ibinder对象进行操作,而我们要获取具体的Service方法的内容的时候,我们需要Ibinder对象返回具体的Service对象才能操作,所以说具体的Service对象必须首先实现Binder对象,这个样子的话我们才能利用bindService的方法对Service进行绑定,获取Binder对象之后获取具体的Service对象,然后才获取Service中的方法等等。所以我们需要注意的是bindService的方式去绑定服务获取的必定是实现了Binder的对象,所以这是我们必须使用Binder的方式去获取Service的方式而不是直接使用Service的类,这个是Android内部实现所约束的。

三.ServiceThread的关系

     一般来说serviceactivity在同一个线程里,即service线程与主线程的Id相同。如下实例所示:

MainActivity中的部分代码:



Myservice中部分代码:

public int onStartCommand(Intent intent,int flags,int startId){

Log.i(TAG"Myservice线程Id:"+Thread.currentThread().getId());

return START_STICKY;

}

效果图:


但如果要用service处理比较耗时间的操作时,就必须创建新的线程,让它们在不同的线程里。提高用户体验。实例如下:

MainActivity中代码不变

Myservice中改变的代码:耗时的代码模拟文件上传


效果图:


一直处于僵持状态5秒,5秒后才能继续操作,这大大降低了用户体验。

解决这一问题,可以创建新线程来操作。

MainActivity中代码不变

Myservice中部分代码:

public int onStartCommand(Intent intent,int flags,int startId){

new MyThread().start(); //创建一个新线程

  

return START_STICKY;

}

  //新建一个类来继承线程,然后实现新线程的方法

private class MyThread extends Thread{

public void run(){

try {

Log.i(TAG"Myser线程Id:"+Thread.currentThread().getId());

Log.i(TAG"文件上传。。。。");

Thread.sleep(5000);

catch (Exception e) {

e.printStackTrace();

}

}

}

效果图:


主线程与service线程不一样了,便于操作。用户操作时不会处于僵持状态。





 





 








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值