Service的两种用法及其生命周期
先来一点基础知识:
Service 是android的四大组件之一,与Activity同属于一个级别,它是运行在后台进行服务的组件(例如在后台播放的音乐,播放音乐的同时并不影响其他操作)。Service与Activity不同,Service没有界面。
Service虽然在后台运行,但是却与Activity一样运行在主程序中,因此不可在Service中进行耗时的操作。如果需要耗时操作的时候,可以开启子线程来操作。
Service的两种用法及其生命周期:
1.startService 开启服务
2.bindService 绑定服务

上图是这两种用法的生命周期图:
1、启动方式:onCreate()->onStartCommand()->onStop()->onDestroy()
2、绑定方式:onCreate()->onBind()->onUnBind()->onDestroy()
~OA.png)
启动服务:一般从活动中调用 startService() ==> 服务调用 onCreate()(创建时只调用一次)==>onStartCommand() (可调用多次)
停止服务:一般从活动中调用 stopService() ==> 服务调用 onDestroy() (只调用一次) 或 直接在服务中调用stopSelf()来停止,如果有绑定服务,得先解绑,才能停止服务
使用方法一:启动服务
例子:服务与Activity的交互
1.在MainActivity中设置两个Button,分别启动服务和停止服务。
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View; public class MainActivity extends ActionBarActivity {
int number=38;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
} public void doButton(View v) {
Intent intent=new Intent();
switch (v.getId()) {
case R.id.button1:
intent.setAction("com.robin.testservice2.action");
intent.putExtra("number", number);
startService(intent);//启动服务
number++;
break; case R.id.button2:
intent.setAction("com.robin.testservice2.action");
stopService(intent);//停止服务
break;
default:
break;
}
}
}
2.建一个Service的子类----这是在执行每两秒cnt自动减1的操作,其代码如下:
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.util.Log; public class MyService extends Service{
protected static final String TAG = "robin debug";
MediaPlayer mp;
Thread printThread;
int cnt=-1;
boolean active=false;
@Override
public IBinder onBind(Intent intent) {
return null;
} @Override
public void onCreate() {
Log.e(TAG,"service create");
super.onCreate();
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG,"service start command");
cnt=intent.getIntExtra("number", -1);
active=true;
printThread=new Thread(){
@Override
public void run() {
while(active){
cnt--;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e(TAG,"progress value--------->"+cnt);
}
}
};
printThread.start();
return super.onStartCommand(intent, flags, startId);
} @Override
public void onDestroy() {
active=false;
super.onDestroy();
Log.e(TAG,"service destroy");
}
}
布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" > <TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" /> <Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_below="@+id/textView1"
android:layout_marginLeft="47dp"
android:layout_marginTop="24dp"
android:text="启动服务"
android:onClick="doButton"/> <Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/button1"
android:layout_below="@+id/button1"
android:layout_marginTop="60dp"
android:text="停止服务"
android:onClick="doButton"/> </RelativeLayout>
以上的操作过程为,在Activity界面点击启动服务(startService(intent);)--->在MyService 中会执行
使用方法二:绑定服务
例子:Service与Activity之间进行通信
先来看看方法之间的调用顺序/过程:

上图中的代码:
ICount.java 类:
package com.robin.testservice3;
public interface ICount { //描述需要的行为(功能)
public int getCount();
public void setCount(int cnt);
}
MainActivity.java
package com.robin.testservice3; import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView; public class MainActivity extends ActionBarActivity {
private ICount count;
private class MyConn implements ServiceConnection{ @Override
public void onServiceConnected(ComponentName name, IBinder binder) {
count=(ICount) binder;
} @Override
public void onServiceDisconnected(ComponentName name) {
count=null;
}
}
MyConn conn=new MyConn();
TextView txt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent service=new Intent("com.robin.testservice3.action");
bindService(service, conn, BIND_AUTO_CREATE);
txt=(TextView)findViewById(R.id.result);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
} public void doButton(View view ){
switch (view.getId()) {
case R.id.button1:
txt.setText("来自service子线程的计数值:"+count.getCount());
break;
case R.id.button2:
count.setCount(1000);
break;
default:
break;
}
}
@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}
}
MyService.java
package com.robin.testservice3; import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log; public class MyService extends Service{
protected static final String TAG = "robin debug";
private boolean active=false;
private int cnt=0;
private class MyBinder extends Binder implements ICount{ @Override
public int getCount() {
return cnt;
}
@Override
public void setCount(int cnt) {
MyService.this.cnt=cnt;
}
}
MyBinder binder=new MyBinder(); @Override
public IBinder onBind(Intent intent) {
return binder;
} @Override
public void onCreate() {
new Thread(new Runnable() { @Override
public void run() {
active=true;
while(active){
cnt++;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e(TAG,"service thread :cnt----->"+cnt); }
}
}).start();
super.onCreate();
}
@Override
public void onDestroy() {
Log.e(TAG,"service call onDestroy");
active=false;
super.onDestroy();
}
}
布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="测试绑定使用service" /> <Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="读service端子线程的计数值"
android:onClick="doButton"/> <Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="修改service端子线程的计数值"
android:onClick="doButton"/> <TextView
android:id="@+id/result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" /> </LinearLayout>

Service的两种用法及其生命周期的更多相关文章
- c++ operator操作符的两种用法:重载和隐式类型转换,string转其他基本数据类型的简洁实现string_cast
C++中的operator主要有两个作用,一是操作符的重载,一是自定义对象类型的隐式转换.对于操作符的重载,许多人都不陌生,但是估计不少人都不太熟悉operator的第二种用法,即自定义对象类型的隐式 ...
- operator 的两种用法
C++,有时它的确是个耐玩的东东,就比如operator,它有两种用法,一种是operator overloading(操作符重载),一种是operator casting(操作隐式转换).1.操作符 ...
- Service的两种启动方法
刚才看到一个ppt,介绍service的两种启动方法以及两者之间的区别. startService 和 bindService startService被形容为我行我素,而bindService被形容 ...
- XFire构建服务端Service的两种方式(转)
XFire构建服务端service的两种方式,一是用xfire构建,二是和spring集成构建. 一,xifre构建,确保把xfire的jar包导入到工程中或classpath. 1,service的 ...
- XFire构建服务端Service的两种方式
1.原声构建: 2.集成spring构建 http://blog.csdn.net/carefree31441/article/details/4000436XFire构建服务端Service的两种方 ...
- JSP中的include的两种用法
1.两种用法 <%@ include file=” ”%> <jsp:include page=” ” flush=”true”/> 2.用法区别 (1)执行时间上区别 < ...
- 子查询。ANY三种用法。ALL两种用法。HAVING中使用子查询。SELECT中使用子查询。
子查询存在的意义是解决多表查询带来的性能问题. 子查询返回单行多列: ANY三种用法: ALL两种用法: HAVING中的子查询返回单行单列: SELECT中使用子查询:(了解就好,避免使用这种方法! ...
- Comparable和Comparator的区别&Collections.sort的两种用法
在Java集合的学习中,我们明白了: 看到tree,可以按顺序进行排列,就要想到两个接口.Comparable(集合中元素实现这个接口,元素自身具备可比性),Comparator(比较器,传入容器构造 ...
- in有两种用法:
# in有两种用法: 1. 在for中. 是把每一个元素获取到赋值给前⾯的变量. 2. 不在for中. 判断xxx是否出现在str中. #len() 为内置函数,输出为1,2,3,4....., 长度 ...
随机推荐
- study topics
永远不变的东西,原理 study roadmap: 1.user space: tizen power manager => suspend/resume or runtime? android ...
- nmap十条常用命令行格式
1) 获取远程主机的系统类型及开放端口 nmap -sS -P0 -sV -O <target> 这里的 < target > 可以是单一 IP, 或主机名,或域名,或子网 - ...
- VBS数组
定义一个数组: dim a(3).这里要注意在VBS里面数组不像其他的例如C,C#,JAVA等数组用[]作为数组标志.VBS采用的是().还需要注意的是,这里定义的数组包含a(0),a(1),a(2) ...
- Scrum学习总结
在学习的过程中,记录一些重要的东东,一为认真学习,作下归纳总结:二为以后查阅,好记性不如烂笔头!如果大家认为太简单,欢迎喷喷^_^ Scrum:一种迭代式增量软件开发过程,通常用于敏捷软件开发.Scr ...
- Qlikview 图标控件实现动态分组
首先编辑一个组合字段,eg, TimeDimension, 内含2个字段(即为动态可以切换的分组字段) 将TimeDimension 作为分组字段.表达式字段 Sum(Sales),结果如图示 在图片 ...
- Redis的主从同步复制
先来看一下Redis的主从同步复制的原理: 在Slave启动并连接到Master之后,它将主动发送一条SYNC命令.此后Master将启动后台存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台 ...
- redis info参数详解
redis 127.0.0.1:6381> info redis_version:2.4.16 # Redis 的版本redis ...
- ---Ubuntu 14.04 虚拟机器和主机时间同步
先把vmware tool 装好! sudo /usr/bin/vmware-toolbox-cmd timesync enable
- linux查看访问windows共享目录NT_STATUS_DUPLICATE_NAME问题解决
linux查看访问windows共享目录NT_STATUS_DUPLICATE_NAME问题解决 [jason@superfreak ~]$ smbclient //powerhouse-smb.my ...
- HashSet中的元素必须重写equals方法和hashCode方法
http://jingyan.baidu.com/article/d5a880eb8fb61d13f147cc99.html 1.为什么必须重写这两个方法. 2.什么事hashSet去重,符合什么样的 ...