**
**
**
Service适用于没有界面,无需用户干预,且需要长期运行的后台功能,其优先级高于Activity,不会轻易被终止,就算被终止,当资源恢复时,它也会自动恢复运行。
Service可以用于后台服务或进程间通信。
**
**
启动->onCreate()->onStartCommand()->运行->停止->onDestroy()->关闭
**
**
使用方式有:启动方式和绑定方式。只有后者才能调用Service对象提供的服务。一般混合使用两种方式。
**
**
服务管理是指服务的启动、运行和停止。在Service中至少要重写onBind方法,用于服务绑定。服务的启动分为隐式启动和显式启动(与启动activity类似)。
(1)显式启动:
startService(new Intent(this,服务类.class));
其中的“this”指运行环境,可以是其它形式。
(2)隐式启动:
要求在注册服务时声明intent-filter的action属性:
启动服务:
startService(服务Intent名)
停止服务:
stopService(服务Intent名)
首次启动服务时,系统运行onCreate()->onStartCommand()(onStart()这个方法已经过期),之后再调用startService(),只调用onStartCommand()。停止服务时会调用onDestroy()方法。
新建一个Service
public class MyService extends Service {
public MyService() {
}
@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();
Toast.makeText(this,"正在执行onCreate",Toast.LENGTH_LONG).show();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this,"正在执行onStart",Toast.LENGTH_LONG).show();
int rd=(int)((Math.random()*100)+1);
String str="生成随机数"+String.valueOf(rd);
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this,"正在执行onDestroy",Toast.LENGTH_LONG).show();
}
然后在activity_main.xml中放两个按钮,分别是启动服务和停止服务按钮
接着在MainActivity中编写代码
public class MainActivity extends AppCompatActivity {
private Intent serviceIntent=null;
private Button start;
private Button stop;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start=(Button)findViewById(R.id.start);
stop=(Button)findViewById(R.id.stop);
serviceIntent=new Intent(this,MyService.class);
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startService(serviceIntent);
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopService(serviceIntent);
}
});
}
}
下面就是运行的结果:
当点击启动服务按钮之后得到如下结果
然后点击关闭服务得到如下结果
看到执行方法onDestroy,表明服务已经停止运行。那么我们用服务生成随机数就实现了。
首先我们修改上面例子中所建立的服务中的代码或者新建一个服务。
public class MyService extends Service {
private Thread thread;
private Runnable bdWork=new Runnable() {
@Override
public void run() {
try {
while(!Thread.interrupted()){
int rd=(int)((Math.random()*100)+1);
MainActivity.UpdateGUI(rd);
Thread.sleep(1000);
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
};
public MyService() {
}
@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();
Toast.makeText(this,"正在执行onCreate",Toast.LENGTH_LONG).show();
thread=new Thread(null,bdWork,"mythread1");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this,"正在执行onStart",Toast.LENGTH_LONG).show();
if(!thread.isAlive()){
thread.start();
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this,"正在执行onDestroy",Toast.LENGTH_LONG).show();
thread.interrupt();
}
}
修改后会发现MainActivity.UpdateGUI(rd)错了,那是因为这事MainActivity当中的方法,我们还没有写,下面我们修改MainActivity中的代码。
public class MainActivity extends AppCompatActivity {
private Intent serviceIntent=null;
private Button start;
private Button stop;
private static Handler handler=new Handler();
private static int rd;
private static TextView tv=null;
private static Runnable refreshLable=new Runnable() {
@Override
public void run() {
tv.setText(String.valueOf(rd));
}
};
public static void UpdateGUI(int rd){
MainActivity.rd=rd;
handler.post(refreshLable);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv=(TextView)findViewById(R.id.tv);
start=(Button)findViewById(R.id.start);
stop=(Button)findViewById(R.id.stop);
serviceIntent=new Intent(this,MyService.class);
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startService(serviceIntent);
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopService(serviceIntent);
}
});
}
}
我们要在activity_main.xml原来的基础上加入一个TextView,如下所示
然后我们就可以运行了,如下便是运行的结果:
点击启动服务后上图中测试数据处会一直产生100以内的随机数,如下图所示
点击关闭服务后,随机数不在变化
服务绑定
这种方法不仅能启动服务,还能获得到服务的连接,通过该连接可以执行服务提供的public方法。
1.我们新建一个服务(Service),然后修改当中的代码
public class MyService extends Service {
private final IBinder mBinder=new LocalBinder();
public class LocalBinder extends Binder {
MyService getService(){
return MyService.this;
}
}
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
Toast.makeText(this,"正在绑定MyService",Toast.LENGTH_LONG).show();
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
Toast.makeText(this,"取消绑定MyService",Toast.LENGTH_LONG).show();
return super.onUnbind(intent);
}
//取随机数
public int getRandomNumber(){
int rd=(int)((Math.random()*100)+1);
return rd;
}
//求和
public int sum(int a,int b){
return a+b;
}
}
然后我们写MainActivity中的代码
public class MainActivity extends AppCompatActivity {
private Button bindService;//绑定服务
private Button unbindService;//取消绑定服务
private Button getNumber1;//取随机数1
private Button getNumber2;//取随机数2
private Button sum;//求和
private TextView tv1;//随机数1
private TextView tv2;//随机数2
private TextView tvSum;//两随机数的和
private int a;//随机数1
private int b;//随机数2
private MyService myService=null;
private ServiceConnection conn=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myService = ((MyService.LocalBinder) service).getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
myService = null;
}
};
@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);
getNumber1=(Button)findViewById(R.id.getNumber1);
getNumber2=(Button)findViewById(R.id.getNumber2);
sum=(Button)findViewById(R.id.qsum);
tv1 = (TextView)findViewById(R.id.tv1);
tv2 = (TextView)findViewById(R.id.tv2);
tvSum = (TextView)findViewById(R.id.sum);
final Intent intent = new Intent(this,MyService.class);
bindService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(myService == null){
bindService(intent,conn,BIND_AUTO_CREATE);
}
}
});
unbindService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
unbindService(conn);
}
});
getNumber1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
a=myService.getRandomNumber();
tv1.setText(String.valueOf(a));
}
});
getNumber2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
b=myService.getRandomNumber();
tv2.setText(String.valueOf(b));
}
});
sum.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tvSum.setText(String.valueOf(myService.sum(a,b)));
}
});
}
}
修改activity_main.xml布局
然后我们运行
注意:我们必须先点击绑定服务按钮,若不先绑定服务,那么当你点击当中除绑定服务按钮的任意按钮时,app将会出现闪退情况。