博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android服务Service
阅读量:4500 次
发布时间:2019-06-08

本文共 9875 字,大约阅读时间需要 32 分钟。

安卓Service服务

    Service简介

        Service是运行在后台的,没有界面的,用来处理耗时比较长的。Service不是一个单独的进程,也不是一个单独的线程。

        Service有两种类型

    本地服务(Local Service):用于应用程序内部

    远程服务(Remote Sercie):用于android系统内部的应用程序之间 

      前者用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好。

      后者可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可。 

  Service的生命周期以及启动方式

      ServicestartService()bindService()两种启动Service方法,每种方法Service的生命周期是不一样的。

     1 通过startService()启动服务

       Service会经历 onCreate() --> onStartCommand() 

       stopService()的时候直接onDestroy() 

       如果是调用者直接退出而没有调用stopService的话,Service会一直在后台运行, 下次调用者再起来仍然可以stopService()

2 通过bindService() 启动服务 

Service会运行onCreate()-->onBind() ,此时调用者和Service绑定在一起

     unbindService()的时候 运行 onUnbind()-->onDestroyed() 

     调用者退出了,Srevice就会调用onUnbind()-->onDestroyed() 

     所谓绑定在一起就共存亡了。 

 

注意ServiceonCreate()的方法只会被调用一次,也就是说无论你多少次的调用startService()或bindService()Service只被创建一次。 

Android中的服务和Windows中的服务是类似的,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。

服务不能自己运行,需要通过调用Context.startService()Context.bindService()方法启动服务。这两个方法都可以启动Service,但是它们的使用场合有所不同。使用startService()方法启用服务,调用者与服务之间没有关联,即使调用者退出了,服务仍然运行。使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止。

如果采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。

如果采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定,也就是说onCreate()onBind()方法并不会被多次调用。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的 onUnbind()-->onDestroy()方法。

三 具体运用

 

1、开始服务,开始服务一般都是界面和服务简单数据交互。示例为从主界面传递一个值给服务,服务接收。

流程:

 

 

示例:

项目工程目录结构:

 

 

主界面,活动页面前台运行
package com.example.service;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public
class MainActivity
extends Activity
{
 Button button1;
 @Override
 
protected
void onCreate ( Bundle savedInstanceState)
 {
  
super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  button1
= (Button)
this.findViewById(R.id.button1);
  button1.setOnClickListener(
new OnClickListener()
  {
   @Override
   
public
void onClick ( View v)
   {
    startMyService();
   }
  });
 }
 
// 服务开启方法
 
protected
void startMyService ()
 {
  Intent intent
=
new Intent(
"com.example.service.MyService");
  
// 利用Intent向服务传递数据,数据通过界面输入
  intent.putExtra(
"myMessage",
"MainActivity--lhyService123456【这是活动前台传递过来的数据】!");
  
this.startService(intent);//开始服务
 }
 @Override
 
public
boolean onCreateOptionsMenu ( Menu menu)
 {
  
// Inflate the menu; this adds items to the action bar if it is present.
  getMenuInflater().inflate(R.menu.main, menu);
  
return true;
 }
}
服务类,后台运行:
package com.example.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public
class MyService
extends Service
{
 @Override
 
public IBinder onBind ( Intent arg0)
 {
  
// TODO Auto-generated method stub
  
return null;
 }
 @Override
 
public
void onCreate ()
 {
  Log.i(
"lhy",
"服务创建onCreate ()-----------");
  
super.onCreate();
 }
 
// 启动服务,目前该方法不用
 
// @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(
"lhy",
"服务开启,在后台运行,正在做事情当中。。。。。。。。。。。。。");
  
// 接收activity传递过来的数据
  String message
= intent.getStringExtra(
"myMessage");
  Log.i(
"lhy",
"MyService--服务后台接收前台活动输入的数据:"
+ message);
  
return
super.onStartCommand(intent, flags, startId);
 }
 @Override
 
public
void onDestroy ()
 {
  
// TODO Auto-generated method stub
  
super.onDestroy();
 }
}
活动前台页面样式布局文件
<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"
android
:paddingBottom
=
"@dimen/activity_vertical_margin"
android
:paddingLeft
=
"@dimen/activity_horizontal_margin"
android
:paddingRight
=
"@dimen/activity_horizontal_margin"
android
:paddingTop
=
"@dimen/activity_vertical_margin"
tools
:context
=
".MainActivity"
>
<TextView
android
:id
=
"@+id/textView1"
android
:layout_width
=
"wrap_content"
android
:layout_height
=
"wrap_content"
android
:layout_marginBottom
=
"10dp"
android
:text
=
"开始服务示例演示"
/
>
<Button
android
:id
=
"@+id/button1"
android
:layout_width
=
"wrap_content"
android
:layout_height
=
"wrap_content"
android
:layout_marginTop
=
"38dp"
android
:text
=
"开始服务"
/
>
<EditText
android
:id
=
"@+id/editText1"
android
:layout_width
=
"match_parent"
android
:layout_height
=
"wrap_content"
android
:layout_alignLeft
=
"@+id/button1"
android
:layout_below
=
"@+id/button1"
android
:layout_marginTop
=
"38dp"
android
:ems
=
"10"
>
<requestFocus
/
>
<
/EditText
>
<
/RelativeLayout
>
AndroidMainfest.xml文件中注册服务
<service android
:name
=
"com.example.service.MyService"
>
<intent
-filter
>
<action android
:name
=
"com.example.service.MyService"
/
>
<
/intent
-filter
>
<
/service
>

控制台输出信息:MainActivity--lhyService123456 是活动界面传递过来,在服务端接收的数据

 

2、绑定服务,一般都是界面与服务深层次数据交互,进程之间数据传递,绑定服务需要连接对象,连接对象中可以获得服务类的内部类对象,这样活动前台可以利用服务类内部类对象操作服务里面的任何方法和属性。

具体流程:

 

示例:

项目工程目录结构:

 

 

活动前台界面
package com.example.servicebind;
import com.example.servicebind.MyServices.MyBind;
import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity
{
 Button button1;
 Button button2;
 MyBind myBind;
 @Override
 protected void onCreate ( Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  button1 = (Button) this.findViewById(R.id.button1);
  button1.setOnClickListener(onClickListener);
  button2 = (Button) this.findViewById(R.id.button2);
  button2.setOnClickListener(onClickListener);
 }
 // 按钮事件监听
 OnClickListener onClickListener = new OnClickListener()
 {
  @Override
  public void onClick ( View v)
  {
   switch (v.getId())
   {
   case R.id.button1:
    startMyServiceBind();
    break;
   case R.id.button2:
    stopMyServiceBind();
    break;
   default:
    break;
   }
  }
 };
 // 按钮点击事件监听方法,也就是绑定服务
 protected void startMyServiceBind ()
 {
  // 如果部内部类对象不为空,那么就直接调用内部类方法,否则重新绑定服务,建立连接
  if (myBind != null)
  {
   // 利用服务内部对象,调用服务内部类方法,相当于调用了服务类的的数据
   myBind.myBindFun();
   Log.i("lhy", myBind.getStr());
  }
  else
  {
   // 绑定服务方法*******************************
   Intent intent = new Intent("com.example.servicebind.MyServices");
   // intent意图,serviceConnection连接, Context.BIND_AUTO_CREATE绑定自动创建
   this.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
  }
 }
 protected void stopMyServiceBind ()
 {
  if (serviceConnection == null)
  {
   return;
  }
  else
  {
   this.unbindService(serviceConnection);
   Log.i("lhy", "服务解除!!");
   serviceConnection = null;
  }
 }
 // 绑定服务开始,类似于事件监听,一个服务连接
 ServiceConnection serviceConnection = new ServiceConnection()
 {
  // 绑定失败之后
  @Override
  public void onServiceDisconnected ( ComponentName name)
  {
   // TODO Auto-generated method stub
  }
  // 绑定成功之后,也就是服务建立了连接
  @Override
  public void onServiceConnected ( ComponentName name, IBinder service)
  {
   // 获取服务类内部对象,IBinder service,该参数就是服务类回调方法OnBind()返回的数据,也就是服务内部对象
   myBind = (MyBind) service;
  }
 };
}
服务类,后台运行
package com.example.servicebind;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class MyServices extends Service
{
 // 服务类成员变量
 String str = "MyServiceMessage";
 // 服务类成员方法
 public void fun1 ()
 {
  Log.i("lhy", "服务内部方法fun1()");
 }
 // 服务类内部类
 public class MyBind extends Binder
 {
  // 内部类调用外部类方法
  public void myBindFun ()
  {
   fun1();
  }
  // 内部类调用外部类成员变量
  public void setStr ( String str)
  {
   MyServices.this.str = str;
  }
  public String getStr ()
  {
   return MyServices.this.str;
  }
 }
 @Override
 public void onCreate ()
 {
  Log.i("lhy", "服务创建onCreate()");
  super.onCreate();
 }
 @Override
 public IBinder onBind ( Intent intent)
 {
  Log.i("lhy", "服务绑定onBind()");
  // 实例化内部类对象,该对象可以无条件调用其外部类(本服务类)的一切方法和成员变量
  return new MyBind();
 }
 @Override
 public boolean onUnbind ( Intent intent)
 {
  Log.i("lhy", "服务解除onUnbind()");
  return super.onUnbind(intent);
 }
}
活动界面布局文件
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="绑定服务演示" />
<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_marginTop="23dp"
android:text="绑定服务" />
<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="14dp"
android:text="解除服务" />
</RelativeLayout>
最后在AndroidMainfest.xml文件中注册服务:
<service android
:name
=
"com.example.servicebind.MyServices"
>
<intent
-filter
>
<action android
:name
=
"com.example.servicebind.MyServices"
/
>
<
/intent
-filter
>
<
/service
>
控制台输出信息:点击【绑定服务】和【解除服务】
 

转载于:https://www.cnblogs.com/leehyuan/p/3389546.html

你可能感兴趣的文章
Linux:xargs命令详解
查看>>
明天你好
查看>>
float浮点数的四舍五入
查看>>
QQ消息记录、接收文件、图片、拍照照片等保存位置
查看>>
IOC与AOP介绍
查看>>
关于求最大公约数
查看>>
Git常用命令学习总结
查看>>
【转载】C#通过Rows.Count属性获取总行数
查看>>
【转载】通过百度站长平台查看网站搜索流量及关键字
查看>>
【转载】Visual Studio2017如何打包发布Winform窗体程序
查看>>
【转载】通过搜狗站长平台手动向搜狗搜索提交死链
查看>>
【转载】通过搜狗站长平台手动向搜狗搜索提交文章加快收录
查看>>
【转载】通过百度站长平台提交网站死链
查看>>
【转载】通过搜狗站长平台提交网站域名变更后的文章地址
查看>>
【转载】Visual Studio2017中如何设置解决方案中的某个项目为启动项目
查看>>
Axios跨域实例
查看>>
ubuntu下安装pyaudio
查看>>
单片机 电子电路 嵌入式 毕设 课设 私活 代做
查看>>
notepad++ 安装 hex_editor 十六进制查看插件
查看>>
正则表达式
查看>>