什么是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. ABAP开发基础知识:内表(Internal Table)

    http://www.cnblogs.com/foxting/archive/2012/03/19/2406830.html 内表与结构体基本类似,它同样是程序运行中被临时创建的一个存储空间,它是一个 ...

  2. 字符流缓冲区BufferedReader之readLine方法的原理

  3. JBOss 端口没占用!

    打开exlipse ,启动服务器 后,报如下错误:

  4. Remastersys打包你自己的ubuntu成iso文件,保存原来的所有配置

    你是不是辛辛苦苦地配好了ubuntu结果不久又重装,然后又重新配置很久呢? 笔者好不容易配置好了torch,但是换硬盘,于是就想到了将ubuntu打包成iso文件,下次直接安装,然后配置好的东西都搬过 ...

  5. PHP流程控制(二)

    布尔型循环就是为真的时候执行,为假的时候停止 注意:1.循环能够节约大量的代码,提高重用性质2.循环,一定要有退出条件.3.While循环中,在while循环之前必须对变量进行初始化; 单层循环:语法 ...

  6. java中调用dll文件的两种方法

    一中是用JNA方法,另外是用JNative方法,两种都是转载来的, JNA地址:http://blog.csdn.net/shendl/article/details/3589676   JNativ ...

  7. 使用ttXactAdmin、ttSQLCmdCacheInfo、ttSQLCmdQueryPlan获取SQL相关具体信息[TimesTen运维]

    使用ttXactAdmin.ttSQLCmdCacheInfo.ttSQLCmdQueryPlan获取SQL相关具体信息,适合于tt11以上版本号. $ ttversion TimesTen Rele ...

  8. Chord算法(原理)

    Chrod算法是P2P中的四大算法之中的一个,是有MIT(麻省理工学院)于2001年提出,其它三大算法各自是: CAN Pastry Tapestry Chord的目的是提供一种能在P2P网络高速定位 ...

  9. Hooks——钩子概览

    (资料源于MSDN,本文仅对其进行翻译.批注.其链接为:http://msdn.microsoft.com/en-us/library/windows/desktop/ms644959%28v=vs. ...

  10. 关于【cocos2dx-3.0beta-制作flappybird】教程在3.2project中出现找不到CCMenuItem.h的解决方法

    文章原文:http://blog.csdn.net/kantian_/article/details/36187141 作者升级源码.能够在3.1平台下执行. 我的是vs2013+cocos2dx-3 ...