什么是Service?

Android中的服务与Activity不同,他是不能与用户进行交互,自己也不能启动在后台运行的程序,当我们退出应用时,Service应用并没有结束,它仍然在后台运行。

例子:

我们播放音乐,此时又要去干别的事的时候。如果没有Services退出播放音乐的应用我们就听不到歌。

如何获取启动Service实例?

可以使用bindService()实现。

初步了解Services的用法:

代码:

 package com.example.hxdn.servicetest;

 import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button; public class MainActivity extends AppCompatActivity { private static final String BiaoQian="MainActivity";
private Button btn1=null;
private Button btn2=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(BiaoQian,"onCreate() executed");
btn1=(Button)findViewById(R.id.btn1);
btn2=(Button)findViewById(R.id.btn2);
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent startIntent=new Intent(MainActivity.this,MyService.class);
startService(startIntent);
}
});
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent stopIntent=new Intent(MainActivity.this,MyService.class);
stopService(stopIntent);
}
}); } @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId(); //noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
} return super.onOptionsItemSelected(item);
}
}
package com.example.hxdn.servicetest;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log; /**
* Created by hxdn on 2015/9/16.
*/
public class MyService extends Service {
public final static String TAG="MyService";
@Override
public void onCreate()
{
super.onCreate();
Log.i(TAG,"onCreate() executed");
}
@Override
public int onStartCommand(Intent intent,int flags,int startId)
{
Log.i(TAG, "onCommand() executed");
return super.onStartCommand(intent, flags, startId); }
@Override
public void onDestroy()
{
super.onDestroy();
Log.i(TAG, "onDestroy() executed");
}
@Override
public IBinder onBind(Intent intent)
{
return null;
}
}
 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hxdn.servicetest"> <application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.example.hxdn.servicetest.MyService"></service>
</application> </manifest>

布局代码只是写两个按钮启动和关闭Setvice。

注意点:

1、Services与Activity同为四大组件都需要注册!

2、如果Services已经创建过(onCreate()),且没有被销毁,接下来再启动Services(startService())只会执行(onStartCommand())。

Service和Activity通信

先贴上代码:

MainActivity:

 package com.example.hxdn.servicetest;

 import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button; public class MainActivity extends AppCompatActivity { private static final String BiaoQian="MyService";
private Button btn1=null;
private Button btn2=null;
private Button btn3=null;
private Button btn4=null;
private MyService.MyBinder mybinder=null;
private ServiceConnection serviceConnection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(BiaoQian,"onServiceConnected() executed");
mybinder=(MyService.MyBinder)service;
mybinder.startDownLoad();
} @Override
public void onServiceDisconnected(ComponentName name) {
Log.i(BiaoQian,"onServiceDisconnected() executed");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(BiaoQian, "onCreate() executed");
btn1=(Button)findViewById(R.id.btn1);
btn2=(Button)findViewById(R.id.btn2);
btn3=(Button)findViewById(R.id.btn3);
btn4=(Button)findViewById(R.id.btn4);
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent startIntent=new Intent(MainActivity.this,MyService.class);
startService(startIntent);
}
});
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i(BiaoQian, "click Stop Service button");
Intent stopIntent=new Intent(MainActivity.this,MyService.class);
stopService(stopIntent);
}
});
btn3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent bindIntent=new Intent(MainActivity.this,MyService.class);
bindService(bindIntent,serviceConnection,BIND_AUTO_CREATE);
}
});
btn4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i(BiaoQian, "click Unbind Service button");
unbindService(serviceConnection);
}
}); } @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId(); //noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
} return super.onOptionsItemSelected(item);
}
}

MyService:

 package com.example.hxdn.servicetest;

 import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log; /**
* Created by hxdn on 2015/9/16.
*/
public class MyService extends Service {
public final static String TAG="MyService";
private MyBinder myBinder=new MyBinder();
@Override
public void onCreate()
{
super.onCreate();
Log.i(TAG,"onCreate() executed");
}
@Override
public int onStartCommand(Intent intent,int flags,int startId)
{
Log.i(TAG, "onCommand() executed");
return super.onStartCommand(intent, flags, startId); }
@Override
public void onDestroy()
{
super.onDestroy();
Log.i(TAG, "onDestroy() executed");
}
@Override
public void onRebind(Intent intent)
{
super.onRebind(intent);
Log.i(TAG,"onRebind() executed");
}
@Override
public boolean onUnbind(Intent intent)
{
Log.i(TAG,"onUnbind()");
return super.onUnbind(intent); }
@Override
public IBinder onBind(Intent intent)//返回类型为IBinder,其主要作用是Service与外界交互的一种手段,
// 而IBinder对象数据类型是接口。
{
return myBinder;
}
class MyBinder extends Binder
{
public void startDownLoad()
{
Log.i(TAG,"startDownLoad() executed");
}
}
}

这里我们新增了一个MyBinder类继承自Binder类,然后在MyBinder中添加了一个startDownload()方法用于在后台执行下载任务,当然这里并不是真正地去下载某个东西,只是做个测试,所以startDownload()方法只是打印了一行日志。

我所理解的Activity与Services通信的机制是:

1、首先Service里需要有一个Binder的类,类似构建起临时的契约。而且需要复写onBind(Intent intent),并返回一个Binder对象。

2、在Activity里需要获得连接,所学需要ServiceConnection的匿名类,在里面重写了onServiceConnected(ComponentName name, IBinder service)

方法和onServiceDisconnected()方法,这两个方法分别会在Activity与Service建立关联和解除关联的时候调用。参数service便是MyService里的onBinder()方法返回的。

便可通过这个这个实例调用Binder类里的方法,我们便可以在Activity中根据具体的场景来调用MyBinder中的任何public方法,即实现了Activity指挥Service干什么Service就去干什么的功能。

3、Activity与Service需要进行绑定

Intent bindIntent=new Intent(MainActivity.this,MyService.class);
bindService(bindIntent,serviceConnection,BIND_AUTO_CREATE);
BIND_AUTO_CREATE:表示绑定后自动创建Service实例。

解绑:
unbindService(serviceConnection);

注意点:
如果我们既点击了Start Service按钮,又点击了Bind Service按钮会怎么样呢?这个时候你会发现,不管你是单独点击Stop Service按钮还是Unbind Service按钮,Service都不会被销毁,必要将两个按钮都点击一下,Service才会被销毁。也就是说,点击Stop Service按钮只会让Service停止,点击Unbind Service按钮只会让Service和Activity解除关联,一个Service必须要在既没有和任何Activity关联又处理停止状态的时候才会被销毁。

Service和Thread的关系

service是后台进程并且运行在主线程,Thread是子线程。

两者没有任何关系。

Android的后台就是指,它的运行是完全不依赖UI的。即使Activity被销毁,或者程序被关闭,只要进程还在,Service就可以继续运行。

面对后台的耗时操作,我们可以在Service写一个子线程。

那为什么不直接在Activity里创建呢?这是因为Activity很难对Thread进行控制,当Activity被销毁之后,就没有任何其它的办法可以再重新获取到之前创建的子线程的实例。而且在一个Activity中创建的子线程,另一个Activity无法对其进行操作。但是Service就不同了,所有的Activity都可以与Service进行关联,然后可以很方便地操作其中的方法,即使Activity被销毁了,之后只要重新与Service建立关联,就又能够获取到原有的Service中Binder的实例。因此,使用Service来处理后台任务,Activity就可以放心地finish,完全不需要担心无法对后台任务进行控制的情况。

一个较为标准的Service:

 @Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(new Runnable() {
@Override
public void run() {
// 开始执行后台任务
}
}).start();
return super.onStartCommand(intent, flags, startId);
} class MyBinder extends Binder { public void startDownload() {
new Thread(new Runnable() {
@Override
public void run() {
// 执行具体的下载任务
}
}).start();
} }

修改by:http://blog.csdn.net/guolin_blog/article/details/11952435

Android开发之Service的更多相关文章

  1. android开发之service详解

    service作为android的四大组件之一,其重要性可想而知,在开发中,我们经常把一些不需要与用户进行交互的工作放在service中来完成,service运行在后台,这样有些人可能会产生错觉,以为 ...

  2. Android开发之Service的写法以及与Activity的通信

    Service的总结: 1.按运行地点分类: 类别 区别  优点 缺点   应用 本地服务(Local) 该服务依附在主进程上,  服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外 ...

  3. Android开发之Service的远程调用

    在Andorid平台中,各个组件运行在自己的进程中,他们之间是不能相互访问的,但是在程序之间是不可避免的要传递一些对象,在进程之间相互通信.为了实现进程之间的相互通信,Andorid采用了一种轻量级的 ...

  4. Android开发之bindService()侦听service内部状态

    在Android开发之bindService()通信的基础上,实现bindService()方法侦听service内部状态. 实现侦听service内部状态,使用的是回调机制 1.首先实现一个接口 p ...

  5. Android开发之旅: Intents和Intent Filters(理论部分)

    引言 大部分移动设备平台上的应用程序都运行在他们自己的沙盒中.他们彼此之间互相隔离,并且严格限制应用程序与硬件和原始组件之间的交互. 我们知道交流是多么的重要,作为一个孤岛没有交流的东西,一定毫无意义 ...

  6. Android开发之Java必备基础

    Android开发之Java必备基础 Java类型系统 Java语言基础数据类型有两种:对象和基本类型(Primitives).Java通过强制使用静态类型来确保类型安全,要求每个变量在使用之前必须先 ...

  7. [置顶] Android开发之MediaPlayerService服务详解(一)

    前面一节我们分析了Binder通信相关的两个重要类:ProcessState 和 IPCThreadState.ProcessState负责打开Binder 驱动,每个进程只有一个.而 IPCThre ...

  8. [置顶] Android开发之serviceManager分析

    Android 开发之serviceManager分析 在Android系统中用到最多的通信机制就是Binder,Binder主要由Client.Server.ServiceManager和Binde ...

  9. Android开发之TextView高级应用

    Android开发之TextView高级应用 我们平时使用TextView往往让它作为一个显示文字的容器,但TextView的功能并不局限于此.以下就和大家分享一下TextView的一些使用技巧. A ...

随机推荐

  1. poj2152 Fire

    好难啊,我弱爆了. 题解看陈启峰的论文... /** * Problem:POJ2152 * Author:Shun Yao * Time:2013.9.2 * Result:Accepted * M ...

  2. tcp/udp socket编程异同

    一.TCP与UDP的区别 基于连接与无连接 对系统资源的要求(TCP较多,UDP少) UDP程序结构较简单 流模式与数据报模式 TCP保证数据正确性,UDP可能丢包 TCP保证数据顺序,UDP不保证 ...

  3. Codeforces Wilbur and Array

    Description Wilbur the pig is tinkering with arrays again. He has the array a1, a2, ..., an initiall ...

  4. 转载 DevOps的基本原则与介绍

    转载原地址:  http://www.cnblogs.com/wintersun/p/3339047.html DevOps的基本原则与介绍 DevOps这个术语是developer与operatio ...

  5. BAT及各大互联网公司2014前端笔试面试题:HTML/CSS篇

    BAT及各大互联网公司2014前端笔试面试题:HTML/CSS篇 2014/08/03 · Web前端, 开发 · CSS, HTML, 技术面试 分享到: 188 MongoDB集群之分片技术应用 ...

  6. 简单dp-poj-2231-Moo Volume

    题目链接: http://poj.org/problem?id=2231 题目大意: 给n个位置,求所有位置到其他n-1个位置的距离总和. 解题思路: 简单dp. o(n^2)的时间复杂度会超.先对这 ...

  7. 【C++深入浅出】设计模式学习之简单工厂

    看大话设计模式中大牛对小菜的精辟点评,也写了一个计算器程序,并跟着点评一路改良,还是不过瘾,应用了类模板和异常捕捉机制重写了程序. 本文不能算干货,恰当的比方是饭前甜点,吃一口有点味.有点意思,总归太 ...

  8. 提高你的Java代码质量吧:少用静态导入

    一.分析  从Java 5开始引入静态导入语法(import static),其目的是为了减少字符输入量,提高代码的可阅读性,以便更好地理解程序. 但是,滥用静态导入会使程序更难阅读,更难维护.静态导 ...

  9. C栈stack

    栈是一种  特殊的线性表 栈仅能在线性表的一端进行操作 栈顶(Top):允许操作的一端 栈底(Bottom):不允许操作的一端 Stack的常用操作 创建栈 销毁栈 清空栈 进栈 出栈 获取栈顶元素 ...

  10. [Effective C++ --018]让接口容易被正确使用,不易被误用

    □第一节 什么是接口?什么是接口?百度百科的解释:两个不同系统(或子程序)交接并通过它彼此作用的部分.接口的概念贯穿于整个软件开发过程中,本文讨论的接口概念仅局限于以C++实现的class,funct ...