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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android中怎么启动关闭Service及功能解释相关的知识,希望对你有一定的参考价值。

  下面根据问题,作出详细解答:

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

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


  启动service有两种方法:

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

    Context.bindService() 调用者与服务绑定在一起,调用者一旦退出,服务也就终止

  Service的生命周期

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

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

    START_STICKY

    START_NOT_STICKY or START_REDELIVER_INTENT


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

    START_STICKY

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

    START_NOT_STICKY

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

    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掉一下存在的进程。因此进程的优先级将会很重要:

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

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

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

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

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

  另外:

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

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

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

参考技术A

是指代码实现吗?

一般分两种

    startService()->stopSelf()/stopService();

    bindService()->onUnBind();

建议看开发文档有相关说明,找个例子练习下,很简单的。

本回答被提问者和网友采纳
参考技术B 1、 Service不是分离开的进程,除非其他特殊情况,它不会运行在自己的进程,而是作为启动运行它的进程的一部分。

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

启动service有两种方法:
1、 Context.startService()
调用者与服务之间没有关联,即使调用者退出,服务仍可运行
2、 Context.bindService()
调用者与服务绑定在一起,调用者一旦退出,服务也就终止

启动关闭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 开机启动后被啥情况下会被自动关闭掉?

设置了开机启动service 打了Log, 显示service 启动成功, onDestroy 方法中的Log没有执行, 不知道service 怎么就自动停止了。 在onCreate 的程序都注掉了,系统服务中还是找不到service服务。

android service 开机启动后被被自动关闭掉原因:
Android 系统对于内存管理有自己的一套方法,为了保障系统有序稳定的运信,系统内部会自动分配,控制程序的内存使用。当系统觉得当前的资源非常有限的时候,为了保 证一些优先级高的程序能运行,就会杀掉一些他认为不重要的程序或者服务来释放内存。这样就能保证真正对用户有用的程序仍然再运行。如果你的 Service 碰上了这种情况,多半会先被杀掉。但如果你增加 Service 的优先级就能让他多留一会,我们可以用 setForeground(true) 来设置 Service 的优先级。
默认启动的 Service 是被标记为 background,当前运行的 Activity 一般被标记为 foreground,也就是说你给 Service 设置了 foreground 那么他就和正在运行的 Activity 类似优先级得到了一定的提高。当让这并不能保证你得 Service 永远不被杀掉,只是提高了他的优先级。
参考技术A 比较费劲的做法是,每次停止后,再到设置——应用程序中,正在运行的程序,把它停止掉;一般情况下这样它不会在自动启动或者装一个程序管理软件,管理这些应用不过有些自带的服务,可能没办法自动关吧.本回答被提问者采纳

以上是关于Android中怎么启动关闭Service及功能解释的主要内容,如果未能解决你的问题,请参考以下文章

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

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

android中启动service的activity销毁了,这时怎么关闭service?

Android 启动后台运行程序(Service)

android service 开机启动后被啥情况下会被自动关闭掉?

Android开发中关闭service的问题