service
service基础
service是一种可以在后台长时间执行运行操作而没有用户界面的应用组件
- service可由activity或者broadcast启动
- service和broadcast都是运行在主线程,不能进行耗时操作
service和Thread区别
定义上
service是Android的一种组件,是由在主线程中的,所以不能进行耗时操作。thread是程序的最小单元,分配CPU的基本单位。主线程(UI线程)也是线程的一种。
实际开发中
service用来做一些数据统计,音乐播放。简单来说就是一个没有UI的activity。如果要在里面进行耗时操作,还得开启一个子线程。
service 两种使用方式
startservice
- 定义一个类继承Service
- 在清单文件中配置Service
- 使用Context的startService(intent)方法启动该Service
不在使用时,调用stopService(intent)方法停止该服务
Intent intent = new Intent(MainActivity.this, TestService.class); //开启服务 startService(intent); //关闭服务 stopService(intent); //在Service内部调用stopSelf方法 stopSelf(); public class TestService extends Service { private String TAG="test_service"; @Nullable @Override public IBinder onBind(Intent intent) { Log.e(TAG, "onBind: " ); return null; } @Override public void onCreate() { super.onCreate(); Log.e(TAG, "onCreate: " ); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.e(TAG, "onStartCommand: "+intent.getStringExtra("service") ); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { Log.e(TAG, "onDestroy: " ); super.onDestroy(); } }
- onCreate方法只会在StartService时候执行一次。如果重复开启服务,只会执行onStartCommand方法。
- 执行了stopService才会执行ondestory方法。这个方法只执行一次。无论执行了多少次stopService。
bindservice
使用场景
特点:
activity和service在不同进程进行交互,
多个activity能绑定一个service
- 同一个进程(同一个app)
- 不同进程(两个app)
- 同一个app不同进程(同2)
基本使用
- 清单文件中配置需要绑定的服务
实现服务类
1、实现一个继承Binder的内部类 2、在onBind方法中返回Binder类的实例 3、实现需要提供的方法
在client(activity、broadcast)中配置
1、绑定服务 bindService(intent,conn,BIND_AUTO_CREATE); 2、建立conn连接 3、解除绑定(如果所有的绑定端client(activity、broadcast)销毁,会自动解除绑定)
final Intent intent = new Intent(this, TestBindService.class);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.e("test_service", "绑定服务: " );
bindService(intent,conn,BIND_AUTO_CREATE);
}
});
Button button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.e("test_service", "解除绑定: " );
unbindService(conn);
}
});
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int count = mServices.getCount();
Log.e("test_service", "getmessage_onClick: " +count);
}
});
Button button3 = (Button) findViewById(R.id.button3);
button3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this,Test2Activity.class));
finish();
}
});
conn=new ServiceConnection(){
/**
* 在这个方法中获取从service中传递过来的iBinder对象,实现宿主与service交互
* @param componentName
* @param iBinder
*/
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.e("test_service", "onServiceConnected: " );
TestBindService.LocalBinder binder = (TestBindService.LocalBinder) iBinder;
mServices = binder.getServices();
}
/**
* 当取消绑定的时候回调,当内存不足的时候也会被执行
* @param componentName
*/
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.e("test_service", "onServiceDisconnected: " );
mServices=null;
}
};
如果多个activity绑定,只在第一次绑定的时候才会执行onCreate、onBind方法。
例如activityA绑定service,跳转到activityB在执行绑定操作。流程如下:activityA-->service(onCreate--onBind--onServiceConnected)-->activityB -->service(onServiceConnected)
如果所有client都结束,则与之建立连接的service会自动销毁。
public class TestBindService extends Service {
private String TAG="test_service";
private int count;
LocalBinder binder=new LocalBinder();
public class LocalBinder extends Binder{
TestBindService getServices(){
return TestBindService.this;
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind: " );
return binder;
}
@Override
public boolean onUnbind(Intent intent) {
Log.e(TAG, "onUnbind: " );
return super.onUnbind(intent);
}
@Override
public void onCreate() {
super.onCreate();
Log.e(TAG, "onCreate: " );
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand: "+intent.getStringExtra("service") );
return super.onStartCommand(intent, flags, startId);
}
public int getCount(){
return count++;
}
@Override
public void onDestroy() {
Log.e(TAG, "onDestroy: " );
super.onDestroy();
}
}
IntentService
由于Service是运行在UI(主)线程中,会带来UI阻塞,所以在操作耗时工作时,都在onStartCommand中开启一个新的线程去执行一些耗时工作。正因为这样,创建一个带有工作线程Service是很常见的(因为工作线程不会阻塞主线程),为了简化程序员工作量,Android额外开发了一个类那就是IntentService
IntentService特点
- 内部实现一个新的工作线程,执行耗时操作
- onHandleIntent方法顺序的执行所有耗时操作
使用方式
- 清单文件中声明一个继承IntentService的类
- 实现类继承IntentService
- 在onHandleIntent方法中实现业务逻辑
使用示例
一般app在初始化的时候有一些第三方平台SDK需要初始化,如果放在Application类里,进行初始化。会影响app的启动速度,所有一般建议在application里开启一个IntentService。在这个IntentService中进行所有SDK的初始化。
public class InitializeService extends IntentService {
private static final String ACTION_INIT_WHEN_APP_CREATE = "com.xingyuyou.xingyuyou.service.action.INIT";
private static Context mContext;
public InitializeService() {
super("InitializeService");
}
public static void start(Context context) {
mContext=context;
Intent intent = new Intent(context, InitializeService.class);
intent.setAction(ACTION_INIT_WHEN_APP_CREATE);
context.startService(intent);
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_INIT_WHEN_APP_CREATE.equals(action)) {
performInit();
}
}
}
private void performInit() {
//空布局初始化
initLoadView();
//下载初始化
x.Ext.init(getApplication());
//工具类初始化
Utils.init(mContext);
//网络初始化
initOkhttp();
//友盟分享
youmeng();
}
}