先来一点基础知识:

  Service 是android的四大组件之一,与Activity同属于一个级别,它是运行在后台进行服务的组件(例如在后台播放的音乐,播放音乐的同时并不影响其他操作)。Service与Activity不同,Service没有界面。

  Service虽然在后台运行,但是却与Activity一样运行在主程序中,因此不可在Service中进行耗时的操作。如果需要耗时操作的时候,可以开启子线程来操作。

Service的两种用法及其生命周期:

1.startService   开启服务

2.bindService    绑定服务

上图是这两种用法的生命周期图:

1、启动方式:onCreate()->onStartCommand()->onStop()->onDestroy()
2、绑定方式:onCreate()->onBind()->onUnBind()->onDestroy()

启动服务:一般从活动中调用 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的两种用法及其生命周期的更多相关文章

  1. c++ operator操作符的两种用法:重载和隐式类型转换,string转其他基本数据类型的简洁实现string_cast

    C++中的operator主要有两个作用,一是操作符的重载,一是自定义对象类型的隐式转换.对于操作符的重载,许多人都不陌生,但是估计不少人都不太熟悉operator的第二种用法,即自定义对象类型的隐式 ...

  2. operator 的两种用法

    C++,有时它的确是个耐玩的东东,就比如operator,它有两种用法,一种是operator overloading(操作符重载),一种是operator casting(操作隐式转换).1.操作符 ...

  3. Service的两种启动方法

    刚才看到一个ppt,介绍service的两种启动方法以及两者之间的区别. startService 和 bindService startService被形容为我行我素,而bindService被形容 ...

  4. XFire构建服务端Service的两种方式(转)

    XFire构建服务端service的两种方式,一是用xfire构建,二是和spring集成构建. 一,xifre构建,确保把xfire的jar包导入到工程中或classpath. 1,service的 ...

  5. XFire构建服务端Service的两种方式

    1.原声构建: 2.集成spring构建 http://blog.csdn.net/carefree31441/article/details/4000436XFire构建服务端Service的两种方 ...

  6. JSP中的include的两种用法

    1.两种用法 <%@ include file=” ”%> <jsp:include page=” ” flush=”true”/> 2.用法区别 (1)执行时间上区别 < ...

  7. 子查询。ANY三种用法。ALL两种用法。HAVING中使用子查询。SELECT中使用子查询。

    子查询存在的意义是解决多表查询带来的性能问题. 子查询返回单行多列: ANY三种用法: ALL两种用法: HAVING中的子查询返回单行单列: SELECT中使用子查询:(了解就好,避免使用这种方法! ...

  8. Comparable和Comparator的区别&Collections.sort的两种用法

    在Java集合的学习中,我们明白了: 看到tree,可以按顺序进行排列,就要想到两个接口.Comparable(集合中元素实现这个接口,元素自身具备可比性),Comparator(比较器,传入容器构造 ...

  9. in有两种用法:

    # in有两种用法: 1. 在for中. 是把每一个元素获取到赋值给前⾯的变量. 2. 不在for中. 判断xxx是否出现在str中. #len() 为内置函数,输出为1,2,3,4....., 长度 ...

随机推荐

  1. Codeforces Round #229 (Div. 2) D

    D. Inna and Sweet Matrix time limit per test 1 second memory limit per test 256 megabytes input stan ...

  2. php curl vs python提交多维数组+文件

    总结: 1.data数据格式 2.php post 格式无需json_encode(关联数组,所以可以绕弯)  参考:http://bbs.csdn.net/topics/390645553?page ...

  3. java测试题总结

    1.Struts2处理来自多个页面的同一个Action请求,那么它们是不是同一个action. struts2中每个请求都是独立的.每一次请求都会去new一个新的action,所有写在action中的 ...

  4. 3,SFDC 管理员篇 - 区域划分

    1,销售区域划分 Setup | Administrator | Manage Territory Territory Type : 帮助用户建立大的销售区域分类,分类顺序按照Priority进行显示 ...

  5. mysql存储过程简介

    创建存储过程CREATE PROCEDURE productpricing(OUT pl DECIMAL(8,2),OUT ph DECIMAL(8,2),OUT pa DECIMAL(8,2))BE ...

  6. 远程操控软件 TeamViewer for MAC 官方中文版11.0.55321

    百度云:https://pan.baidu.com/s/1o77ol2y 提取密码:3tsx windows: http://download.pchome.net/internet/server/r ...

  7. delphi检查url是否有效的方法

    function CheckUrl(url: string; TimeOut: integer = 5000): boolean;var hSession, hfile, hRequest: hInt ...

  8. 获取Spring容器中的Bean

    摘要 SpringMVC框架开发中可能会在Filter或Servlet中用到spring容器中注册的java bean 对象,获得容器中的java bean对象有如下方法 Spring中的Applic ...

  9. C#页面前台绑定数据 <%%><%#%><%=%>

    ASP.net前台绑定用的最多,今天小小总结一下. 1:<%#Eval("")%> 2:<%#Bind("")%> 3:<%=变量 ...

  10. /etc/hosts文件设置不对导致Jboss启动失败

    Caused by: javax.management.MBeanRegistrationException: preRegister() failed: [ObjectName='jboss.rem ...