先来一点基础知识:

  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. CentOS6.5下安装apache2.2和PHP 5.5.28

    CentOS6.5下安装apache2.2 1. 准备程序 :httpd-2.2.27.tar.gz 下载地址:http://httpd.apache.org/download.cgi#apache2 ...

  2. AngularJs 入门系列-2 表单验证

    对于日常的开发来说,最常见的开发场景就是通过表单编辑数据,这里涉及的问题就是验证问题. angularjs 内置已经支持了常见的验证方式,可以轻松实现表单验证. 1. 绑定 为了方便,我们在 $sco ...

  3. vs2013_arcgis_developer_kit_101_install

    1.修改注册表以安装AE101 在注册表中HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0增加类型为REG_SZ的 ...

  4. MSSQLSERVER之发布-分发-订阅

    一.环境 发布服务器 O S: Windows servier 2003 64位 Soft: Microsoft SqlServer 2008 R2 I P: 192.168.3.70 HOST-NA ...

  5. 文章“Redcing the Dimensiongality of Data with Neural Networks”的翻译

    注明:本人英语水平有限,翻译不当之处,请以英文原版为准,不喜勿喷,另,本文翻译只限于学术交流,不涉及任何版权问题,若有不当侵权或其他任何除学术交流之外的问题,请留言本人,本人立刻删除,谢谢!! 本文原 ...

  6. QuerySet转化为JSON

    import json data = json.dumps(list(my_table.objects.all().values())) return HttpResponse(data)

  7. 使用imap协议接收邮件

    之前一直使用PHPMail类进行发送邮件,这个是一个非常强大的类,但是其实底层就是使用mail()函数来进行发送的. 但是现在公司有个需求是  写个程序需要实时的接收邮件,主要是判断邮件发出去了,并且 ...

  8. BCB 中测量Richedit 的文本总行高

    RICHEDIT 富文本控件可以容纳各种字体,那么如果我们想要知道文本的总行高如何做呢? 比如,我们想判断,richedit中的文本内容有没有超出richedit 的范围,如何实现呢? 1,需要使用E ...

  9. angularjs 延迟更新和angularjsUI

    angularjsUI库https://material.angularjs.org/latest/ ng-model-options="{ updateOn: 'blur' }" ...

  10. Linux搭建smtp服务器+laravel5.2发邮件配置

    /** * 这里主要是想通过自己搭建smtp服务器,配置laravel5.2框架,实现邮箱发邮件功能, * 主要内容是搭建smtp服务器,laravel5.2发邮件顺手提一下 */ /** * 1.l ...