`
mmdev
  • 浏览: 12916339 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

Android中怎么启动关闭Service及功能解释 .

 
阅读更多

什么是Service?

解惑:

1、 Service不是分离开的进程,除非其他特殊情况,它不会运行在自己的进程,而是作为启动运行它的进程的一部分。

2、 Service不是线程,这意味着它将在主线程里劳作。

启动service有两种方法:

1、 Context.startService()

调用者与服务之间没有关联,即使调用者退出,服务仍可运行

2、 Context.bindService()

调用者与服务绑定在一起,调用者一旦退出,服务也就终止

Service的生命周期

如果使用startService()启动service,系统将通过传入的Intent在底层搜索相关符合Intent里面信息的service。如果服务没有启动则先运行onCreate,然后运行onStartCommand (可在里面处理启动时传过来的Intent和其他参数),直到明显调用stopService或者stopSelf才将停止Service。无论运行startService多少次,只要调用一次stopService或者stopSelf,Service都会停止。使用stopSelf(int)方法可以保证在处理好intent后再停止。

控制service运行的主要方式有两种,主要是根据onStartCommand方法返回的数值。方法:

1、START_STICKY

2、START_NOT_STICKY or START_REDELIVER_INTENT

这里主要解释这三个变量的意义:

1、 START_STICKY

在运行onStartCommand后service进程被kill后,那将保留在开始状态,但是不保留那些传入的intent。不久后service就会再次尝试重新创建,因为保留在开始状态,在创建 service后将保证调用onstartCommand。如果没有传递任何开始命令给service,那将获取到null的intent

2、 START_NOT_STICKY

在运行onStartCommand后service进程被kill后,并且没有新的intent传递给它。Service将移出开始状态,并且直到新的明显的方法(startService)调用才重新创建。因为如果没有传递任何未决定的intent那么service是不会启动,也就是期间onstartCommand不会接收到任何null的intent。

3、 START_REDELIVER_INTENT

在运行onStartCommand后service进程被kill后,系统将会再次启动service,并传入最后一个intent给onstartCommand。直到调用stopSelf(int)才停止传递intent。如果在被kill后还有未处理好的intent,那被kill后服务还是会自动启动。因此onstartCommand不会接收到任何null的intent。

客户端也可以使用bindService来保持跟service持久关联。谨记:如果使用这种方法,那么将不会调用onstartCommand(跟startService不一样,下面例子注释也有解析,大家可试试)。客户端将会在onBind回调中接收到IBinder接口返回的对象。通常IBinder作为一个复杂的接口通常是返回aidl数据。

Service也可以混合start和bind一起使用。

权限

要运行service,首先必须在AndroidManifest.xml里申明<service>标签。

Service能够保护个人的IPC调用,所以在执行实现该调用时前先使用checkCallingPermission(String) 方法检查是否有这个权限。

进程生命周期

当service运行在低内存的环境时,将会kill掉一下存在的进程。因此进程的优先级将会很重要:

1、 如果service当前正在执行onCreate、onStartCommand、onDestroy方法,主进程将会成为前台进程来保证代码可以执行完成避免被kill

2、 如果service已经启动了,那么主进程将会比其他可见的进程的重要性低,但比其他看不见的进程高。因为只有少部分进程始终是用户可见的,因此除非在极度低内存的时候,不然 service是不会被kill的。

3、 如果有客户端关联到service,那么service永远比客户端重要。也就是说客户端可见,那么service也可见(我理解这里的可见并不是可以看到,而是重要性,因为可见往往就表示重要性高)。

4、 Service可以使用startForeground API将service放到前台状态。这样在低内存时被kill的几率更低,但是文档后面又写了,如果在极度极度低内存的压力下,该service理论上还是会被kill掉。但这个情况基本不用考虑。

当然如果service怎么保持还是被kill了,那你可以通过重写onStartCommand返回变量来设置它的启动方式。比如:START_STICKY、START_REDELIVER_INTENT等等,前面已经讨论了它们的作用,这里就不再累赘了

另外:

service 的onCreate和onStartCommand 是运行在主线程的,所以如果里面有处理耗时间的任务。两种处理:

1、 请将它们都挪到新的线程里。

2、 用系统提供的IntentService,它继承了Service,它处理数据是用自身新开的线程。

启动关闭service实例

===================main文件========================

package com.services.coms;

import java.io.FileFilter;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainService extends Activity {
private TextView textviewService;
private Button buttonStart ,buttonStop;
public static final int CMD_STOP_SERVICE = 0;
DataReceiver dateReceiver;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textviewService=(TextView)findViewById(R.id.textservice);
buttonStart=(Button)findViewById(R.id.buttonstart);
buttonStop=(Button)findViewById(R.id.buttonstop);
buttonStart.setOnClickListener(buttonClick);
buttonStop.setOnClickListener(buttonClick);
}

private View.OnClickListener buttonClick =new View.OnClickListener() {
@Override
public void onClick(View v) {
if(v==buttonStart){
Intent intentService=new Intent(MainService.this,MyService.class);
startService(intentService);
Log.i("onStartCommand", "OnClickListener=");
}else if(v==buttonStop){
Intent intent=new Intent();
intent.setAction("AAAAA");
intent.putExtra("cmd",CMD_STOP_SERVICE);
sendBroadcast(intent);
}

}
};
private class DataReceiver extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
Log.i("onStartCommand", "接受要更新的广播数据="+intent.getStringExtra("data"));
String Date=intent.getStringExtra("data");
textviewService.setText(Html.fromHtml("<font color='#0066CC'><u>"+"Service的数据为:"+Date+"</font>"));
}
}
@Override
protected void onStart() {
dateReceiver=new DataReceiver();
IntentFilter intentfilter=new IntentFilter();// 创建IntentFilter对象
intentfilter.addAction("AAAAA");
registerReceiver(dateReceiver, intentfilter);// 注册Broadcast Receiver
super.onStart();
}
@Override
protected void onStop() {
unregisterReceiver(dateReceiver);// 取消注册Broadcast Receiver
super.onStop();
}


}

===================service文件===================

package com.services.coms;

import java.util.UUID;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.os.IBinder;
import android.util.Log;

public class MyService extends Service {

CommandReceiver cmdReceiver;
boolean flag;

@Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
}

@Override
public void onCreate() {
cmdReceiver=new CommandReceiver();
flag=true;
Log.i("onStartCommand", "onCreate=");
super.onCreate();
}

@Override
public void onDestroy() {
this.unregisterReceiver(cmdReceiver);// 取消BroadcastReceiver
super.onDestroy();
}

@Override
public void onLowMemory() {
// TODO Auto-generated method stub
super.onLowMemory();
}

@Override
public void onRebind(Intent intent) {
// TODO Auto-generated method stub
super.onRebind(intent);
}

@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("onStartCommand", "onStartCommand=");
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction("AAAAA");
registerReceiver(cmdReceiver, intentFilter);
doJob();// 调用方法启动线程

return super.onStartCommand(intent, flags, startId);
}

@Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
return super.onUnbind(intent);
}

@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}

//接受广播
private class CommandReceiver extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
int cmd=intent.getIntExtra("cmd", -1);
if(cmd==MainService.CMD_STOP_SERVICE){//如果等于0
flag=false;//停止线程
stopSelf();//停止服务
}
}

}
public void doJob(){
new Thread(){
@Override
public void run() {
while(flag){//如果==true执行发送广播
try {
Thread.sleep(1000);//休眠1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i("onStartCommand", "run=");
Intent intent=new Intent();
intent.setAction("AAAAA");
intent.putExtra("data",UUID.randomUUID()+"");
sendBroadcast(intent);//发送广播名称aaaaa 参数名字data

}
}
}.start();
}
}


==================layout文件=====================

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/textservice"
></TextView>
<Button
android:id="@+id/buttonstart"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="启动服务"
android:gravity="center"
></Button>
<Button
android:id="@+id/buttonstop"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="停止服务"
android:gravity="center"
></Button>
</LinearLayout>

分享到:
评论

相关推荐

    Android Service中方法使用详细介绍

    在Android中,Activity主要负责前台页面的展示,Service主要负责需要长期运行的任务。例如,一个从service播放音乐的音乐播放器,应被设置为前台运行,因为用户会明确地注意它的运行.在状态栏中的通知可能会显示...

    新版Android开发教程.rar

    ----------------------------------- Android 编程基础 1 封面----------------------------------- Android 编程基础 2 开放手机联盟 --Open --Open --Open --Open Handset Handset Handset Handset Alliance ...

    用Service来启动背景音乐

    不要忘了,Android的四大组件中,有一个Service。它的功能类似于Activity,只是Service是在后台工作,不出现在用户的视野中。当我们在前台上进行一个人机交互操作,让这个操作关联到Service上,这样,我们就能够解决...

    如何设计android锁屏程序.pptx

    主要功能 当屏幕关闭时锁屏程序启动 绘制解锁图形解锁 设置解锁图形 如何设计android锁屏程序全文共27页,当前为第5页。 主要功能 设计自己的service 设计自己的activity页面 重载自己的view 如何设计android锁屏...

    Android代码-android-UCToast

    本项目模拟实现该功能,即:开机自动启动的 Service 监听剪切板。复制之后,在屏幕顶部显示一个悬浮窗,显示剪贴板内容。点击悬浮窗,跳转到 Activity 页面显示。 兼容到 API level 9。 包含以下几个小功能点: ...

    android开发音乐盒的实验报告.doc

    (4)在src文件中的文件中的Sample_9_3.java中定义一些按钮和转换的方法,在MySer vice.java中实现了按钮,在songwords.java中实现了歌词那个界面的功能。 三、系统设置 1、功能设计 这个播放器可以实现播放,暂停...

    8941-Android智能手机编程.docx

    应用组件是Android应用程序的重要基石,每个组件都可以作为独立的实体存在,支持具体的功能实现。 8941-Android智能手机编程全文共17页,当前为第3页。 (1)Activity(活动) 8941-Android智能手机编程全文共17页...

    西安android开发

    让我更加熟练Android软件的开发,为以后工作打下坚实的基础,音乐播放是一个比较特殊的功能,在制作过程中遇到了很多问题,比如当关闭主界面音乐就会停止,但是完善的音乐播放器就不会出现这种情况,最终还是学会...

    Android应用开发实验指导书.doc

    完成Android开发平台的搭建及相关配置 2. 创建项目并熟悉文件目录结构 3. 实现例程HelloWorld 实验内容 一、安装并配置Java JDK 1. 下载安装JDK,如安装目录为:C:\Program Files (x86)\Java\jdk1.6.0_18。 2. 配置...

    疯狂Android讲义.part2

    4.1.3 启动、关闭Activity 179 4.1.4 使用Bundle在Activity之间 交换数据 181 4.1.5 启动其他Activity并返回结果 185 4.2 Activity的回调机制 189 4.3 Activity的生命周期 190 4.3.1 Activity的生命周期演示 190 ...

    疯狂Android讲义.part1

    4.1.3 启动、关闭Activity 179 4.1.4 使用Bundle在Activity之间 交换数据 181 4.1.5 启动其他Activity并返回结果 185 4.2 Activity的回调机制 189 4.3 Activity的生命周期 190 4.3.1 Activity的生命周期演示 190 ...

    Rk3399 获取系统ROOT权限补丁7.1与8.1.rar

    4、此补丁运用于Android7.1版本,需要在补丁中把vendor目录都修改为system目录,并且关闭system分区的verity功能 ( 关闭system分区的verity功能: device/rockchip/common/device.mk 中根据注释,注释掉...

    疯狂Android讲义源码

     4.1.3 启动、关闭Activity 179  4.1.4 使用Bundle在Activity之间  交换数据 181  4.1.5 启动其他Activity并返回结果 185  4.2 Activity的回调机制 189  4.3 Activity的生命周期 190  4.3.1 Activity的生命...

    Android蓝牙通信框架BluetoothKit.zip

    BluetoothKit是一款功能强大的Android蓝牙通信框架,支持经典蓝牙和低功耗蓝牙设备混合扫描,提供了一系列简单易用的接口用于低功耗蓝牙设备的连接,数据读写,通知等。 特点 一、支持经典蓝牙和BLE蓝牙...

    adb1.0.26包含fastboot.exe

    注意这个状态并不能标识 Android 系统已经完全启动和可操作,在设备启动过程中设备实例就可连接到 adb,但启动完毕后系统才处于可操作状态。 no device —— 没有设备/模拟器连接。 以上输出显示当前已经连接了...

    Google Android SDK开发范例大全(完整版附部分源码).pdf

    Google Android SDK开发范例大全(完整版) 包含部分书中源码 目录 第1章 了解.深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 ...

Global site tag (gtag.js) - Google Analytics