android service 阻塞ui,Android——Service 服务

本文详细介绍了Android中的Service,包括Service的适用场景、生命周期及startService与bindService的区别。重点讲解了如何避免Service阻塞UI线程,以及创建前台Service的必要性和实现方法。此外,还探讨了IntentService的使用优势以及如何通过AIDL实现进程间通信。
摘要由CSDN通过智能技术生成

描述

Service通常总是称之为“后台服务”,其中“后台”一词是相对于前台而言的,具体是指其本身的运行并不依赖于用户可视的UI界面;

因此,从实际业务需求上来理解,Service的适用场景应该具备以下条件:

1、并不依赖于用户可视的UI界面(当然,这一条其实也不是绝对的,如前台Service就是与Notification界面结合使用的);

2、具有较长时间的运行特性。

Service特性

1、Service本身都是运行在其所在进程的主线程(如果Service与Clinet同属于一个进程,则是运行于UI线程),但Service一般都是需要进行”长期“操作,所以经常写法是在自定义Service中处理”长期“操作时需要新建线程,以免阻塞UI线程或导致ANR;

2、Service一旦创建,需要停止时都需要显示调用相应的方法(startService需要调用stopService()或Service本身调用stopSelf(..);

bindService需要调用unbindService(),否则对于startService将处于一直运行状态,对于bindService,当Client生命周期结束时也将因此问题。也就是说,Service执行完毕后,必须人为的去停止它。

startService

startService()启动Service后,此时Service的生命周期与Client本身的什么周期是没有任何关系的;

使用步骤如下:

1、创建Service子类,继承自Service

2、在AndroidManifest文件中注册Service:

项目中的每一个Service都必须在AndroidManifest.xml中注册才能生效。

3、启动Service:

当第一次启动Service的时候,会调用该Service中的onCreate()和onStartCommand(Intent intent, int flags, int startId)方法。若再次启动Service,onCreate()不会被调用,只有onStartCommand(Intent intent, int flags, int startId)方法才会调用。其中参数flags默认情况下是0,对应的常量名为START_STICKY_COMPATIBILITY。startId是一个唯一的整型,用于表示此次Client执行startService(...)的请求请求标识,在多次startService(...)的情况下,呈现0,1,2....递增。

4、销毁Service:

无论多少次的startService,只需要一次stopService()即可将此Service终止,执行onDestroy()函数(其实很好理解,因为onDestroy()与onCreate()回调是相对的)。

5、注意点:

5.1、当用户强制kill掉进程时,onDestroy()是不会执行的。

5.2、对于同一个Service,Service实例一次永远只存在一个,而不管Client是否是相同的组件,也不管Client是否处于相同的进程中。

5.3、Service通过startService(..)启动Service后,此时Service的生命周期与Client本身的什么周期是没有任何关系的,只有Client调用stopService(..)或Service本身调用stopSelf(..)才能停止此Service。当然,当用户强制kill掉Service进程或系统因内存不足也可能kill掉此Service。

5.4、Client A 通过startService()启动Service后,可以在其他Client(如Client B、Client C)通过调用stopService()结束此Service。

5.5、Client调用stopService()时,如果当前Service没有启动,也不会出现任何报错或问题,也就是说,stopService()无需做当前Service是否有效的判断。

5.6、当Service需要运行在单独的进程中,AndroidManifest.xml声明时需要通过android:process指明此进程名称,当此Service需要对其他App开放时,android:exported属性值需要设置为true(当然,在有intent-filter时默认值就是true)。

自定义Service

public class MyService extends Service {

public static final String TAG = "MyService";

@Override

public void onCreate() {

super.onCreate();

Log.e(TAG, "onCreate() executed");

}

@Override

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

Log.e(TAG, "onStartCommand() executed");

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

}

@Override

public void onDestroy() {

super.onDestroy();

Log.e(TAG, "onDestroy() executed");

}

//返回具体的IBind对象

@Override

public IBinder onBind(Intent intent) {

return null;

}

}

在AndroidManifest文件中注册Service

android:name=".MyService"

android:exported="false">

startService

public class ServiceTestOneActivity extends BaseActivity

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_service_test);

Log.e("ServiceTestOneActivity",

"ServiceTestOneActivity thread id is " + Thread.currentThread().getId());

findViewById(R.id.bt_start).setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Intent startIntent = new Intent(ServiceTestOneActivity.this, MyService.class);

startService(startIntent);

}

});

findViewById(R.id.bt_stop).setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Intent stopIntent = new Intent(ServiceTestOneActivity.this, MyService.class);

stopService(stopIntent);

}

});

}

@Override

protected void onDestroy() {

super.onDestroy();

}

}

bindService

bindService的主要特性在于Service的生命周期是依附于Client的生命周期的,当Client销毁时,bindService将执行onDestroy。

同时通过Service中的Binder对象可以较为方便进行Client-Service通信。bindService一般使用过程如下:

1、创建Service子类,继承自Service,并重写onBind(Intent intent)方法,此方法中需要返回具体的Binder对象。

2、Client通过实现Serv

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值