您的位置:首页 > 其它

Service简单学习

2016-07-17 16:05 375 查看
第一:什么是Service?

Service是四大组件之一,Service与Activity相似,我们知道什么是Activitiy就好容易理解什么是Service,Service与Activity最大区别就在于Activity是负责与用户交互的,有界面,用户可视,而Service是没有用户界面的,位于后台,为整个程序提供服务的。Service与Activity都是Context派生出来的,因此也可以调用Context的方法。

第二:创建与配置Service

(1)创建一个继承自Service的类,实现父类的几个方法

(2)在AndroidMenifest中使用service标签声明

第三:

了解Service的生命周期,使用startService()与bindService()启动的Service生命周期不一样,简单的画了个图



从图中可以看出,startService中在onCreate之后进入到onStartCommand就开始运行,相关逻辑就在onCreate和onStartCommand方法中操作,bindService中在onCreate之后,还会走onBind方法,进入onBind()方法,Service开始运行,相关逻辑代码,在onBind方法中编写,当用户点击退出服务时,即调用了unBind方法,之后

会走onDestory方法,

自己编写了一个简单的启动Service的程序,什么操作也没有,仅仅在生命周期中打印了几条日志

启动服务界面代码:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button bind, unBind;
Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bind = (Button) findViewById(R.id.bind);
unBind = (Button) findViewById(R.id.unbind);
bind.setOnClickListener(this);
unBind.setOnClickListener(this);
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bind:
intent=new Intent(MainActivity.this,MyService.class);
startService(intent);
break;
case R.id.unbind:
stopService(intent);
break;
}
}
}


Service类代码:

public class MyService extends Service{
@Nullable
@Override
public IBinder onBind(Intent intent) {

Log.d("MyService", "onBind");

return null;
}

@Override
public void onCreate() {
super.onCreate();
Log.d("MyService", "onCreate");
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("MyService", "onStartCommand");
return super.onStartCommand(intent, flags, startId);
}

@Override
public void onDestroy() {
super.onDestroy();
Log.d("MyService", "onDestroy");
}
}


代码很简单,主界面是两个按钮一个start 一个stop

当点击一次start时,日志中输出了oncreat和onstartCommand,当点击三次时,输出一次onCreate三次onstartCommand

如图



也就是只有在第一次启动时会走onCreate,其他时候每次启动只会回调onstartCommand,不会回调onCreate,除非程序结束再次启动。当我点击stop时,走了onDestory,再次点击start才又走了onCreate,



注:代码中不要受我Button命名的影响,我是和bindService共用xml所以命了bind与unbind的名,实际上这里应该是start与stop才合适。

- 第四: Service的启动

启动Service的方法有两种

一种是通过Context的startService()方法,一种是Context的bindService方法

这两种方法的差异就是,startService()方法,访问者与Service之间几乎没有关联,即使访问者退出了,Service仍然运行,因此,Service与访问者之间也不能进行通信和数据的交换tService()方法启动,而bindService方法访问者与Service关联在一起,访问者退出,Service也退出,两者之间也可以进行相互通信,至于如何通信,后面来记。

这里有一条必须注意:Android5.0后要求必须使用显示Intent启动服务组件。

第五:绑定本地Service并与之通信

第四步已经说了通过startService启动的服务与访问者几乎没有关联,两者之间也不能进行通信与数据交换,要实现通信和数据交换应该通过bindService启动,bindService的

完整标签为:bindService(Intent service, ServiceConnection conn,

int flags)

参数解释:

参数1:service为要启动的service对象

参数2:conn是一个ServiceConnection 对象,该对象用于监听service与Activity的连接状态,连接成功回调onServiceConnected(ComponentName name, IBinder service)方法,连接失败调用onServiceDisconnected(ComponentName name) 方法,这里需要注意,onServiceDisconnected方法是连接失败时回调的方法,如果是访问者自己解绑是不会回调这个方法的,而是执行unbindService(ServiceConnection conn) 。

参数3:flags指定如果service还没有创建,是否自动创建,

注意到onServiceConnected(ComponentName name, IBinder service)这个方法中有一个IBinder 参数,这个参数就是Service类中IBinder onBind(Intent intent)返回的对象,可以通过这个对象实现Activitiy与Service的通信与数据交换。

下面这个小程序就是实现onBind方法并返回一个有效的IBind对象,

相关代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<Button
android:id="@+id/bind"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="绑定服务"/>

<Button
android:id="@+id/unbind"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="解绑服务"/>

<Button
android:id="@+id/state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="获取连接状态"/>

</LinearLayout>


布局文件是三个按钮分别为,绑定服务解绑服务和获取服务状态

Service类相关代码

public class MyService_bind extends Service {
private int count;
private boolean quit;

private MyBinder mMyBinder = new MyBinder();

@Nullable
@Override
public IBinder onBind(Intent intent) {

System.out.println("service is binded");

return mMyBinder;
}

@Override
public void onCreate() {
System.out.println("Service is  created");
//启动一个线程,用来动态改变count的值

new Thread() {
@Override
public void run() {
while (!quit) {
try {
Thread.sleep(1000);

} catch (InterruptedException e) {

}
count++;
}
}
}.start();

}

//service断开连接时回调的方法
@Override
public boolean onUnbind(Intent intent) {
System.out.println(" service is unbind");
return true;
}

@Override
public void onDestroy() {
this.quit = true;
System.out.println("service is destory");
}

//实际开发中会使用继承自Binder的方式实现自己的IBinder对象,
public class MyBinder extends Binder {

public int getCount() {
return count;
}

}

}


主界面相关代码

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button bind, unBind, state;

Intent intent;
MyService_bind.MyBinder mMyBinder;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bind);
bind = (Button) findViewById(R.id.bind);
unBind = (Button) findViewById(R.id.unbind);
state = (Button) findViewById(R.id.state);
state.setOnClickListener(this);
bind.setOnClickListener(this);
unBind.setOnClickListener(this);
}

//
private ServiceConnection mServiceConnection = new ServiceConnection() {
//Activity与Service连接成功回调的方法
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("Service  is  connected");
//赋值,强转。
mMyBinder = (MyService_bind.MyBinder) service;
}

//Activity与Service连接失败回调的方法,如果是访问者自动解绑,不会调用这个方法
@Override
public void onServiceDisconnected(ComponentName name) {
//
System.out.println("Service is disconnect");

}
};

@Override
public void onClick(View v) {

intent = new Intent(MainActivity.this, MyService_bind.class);
switch (v.getId()) {
case R.id.bind:
bindService(intent, mServiceConnection, BIND_AUTO_CREATE);

break;
case R.id.unbind:
unbindService(mServiceConnection);
break;
case R.id.state:
Log.i("chen","Service的count值    为"+mMyBinder.getCount());
break;
}
}
}


运行程序,点击绑定服务

输出如下


既然链接成功了,再来获取数据,点击第三个按钮,输出如下



多次点击取值,看到输出count按照程序连续加一

然后点击解绑



输出unbind和destroy

在解绑后我再次点击获取值,输出的任意count值,并且不变都是66,这个时候点击绑定—>取值就会看到再次服务重新创建并且连接成功,输出不断增加的count值



简单的程序就到这里,实际开发中可以让MyBinder去操作Service中的更多数据,取决于业务需求。

bindService与startService还有一点不同的是无论点击多少次bindService都只会绑定一次,二startService多次点击却是会多次调用onstartCommand启动多次。

最近在看android讲义,用博客把知识梳理了一遍,增强了理解,目前先了解这么多,实际还要在开发中多多运用才能更好地掌握,下一次了解IntentService的使用,。

本人管理了一个群,这个群创建不久,现在人数也不多,希望有意一起交流技术的朋友们加群一起交流,让群越来越活跃,群内人员互相学习越来越厉害:群号: 361629723
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  service