先来一点基础知识:

  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. weblogic 优化设置 http://wenku.baidu.com/view/c42e7a5bbe23482fb4da4cf2.html

    引自:http://wenku.baidu.com/view/c42e7a5bbe23482fb4da4cf2.html

  2. CoolTrayIcon4.0

    CoolTrayIcon:在任务栏放置图标的控件,是同类空间中功能最为完善和强大的. 1.支持动态图标 2.交互式气球样式的提示框 3.支持bitmaps到icons的转换 4.支持设计状态预览 5. ...

  3. Android:去掉默认的标题bar

    要使用自己定义的bar,只需要在layout文件中添加:<include layout="@layout/actionbar" />;当然你需要新建一个actionba ...

  4. Create User - mysql

    Create User MariaDB [(none)]> CREATE USER 'DBAdmin'@'%' IDENTIFIED BY 'mypasswd';Query OK, 0 rows ...

  5. 使用opencv设置图像的格式以及帧率

    最近楼主正在写一个关于图像存储的程序,LZ有一颗求知心,想要了解保存的图像的格式以及获取摄像头帧率.晚些时候会写一篇关于opencv获取摄像头并且保存每帧图像信息方法. 1.修改图像的像素显示: 首先 ...

  6. React 附件动画API ReactCSSTransitionGroup

    React为动画提供了一个附加组件ReactTransitionGroup,这个附加组件是动画的底层API,并且还提供了一个附件组件ReactCSSTransitionGroup,ReactCSSTr ...

  7. app的meta标签

    1.规定网页编码 <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> ...

  8. express 手动删除session状态(即登出功能)

    在退出按钮被点击后,发送请求/logout,服务端做如下处理: app.get('/logout', function() { delete req.session.user; return res. ...

  9. C# 自定义序列化问题

        public class overdue     {         public int overdueTimes { get; set; }         /// <summary ...

  10. go特性学习

    而后我写了一些测试代码: dept1 :=     Dept{         name:     "MySohu",         building: "Intern ...