安卓基础总结 Service相关

来源:互联网 发布:轮回转世是真的吗 知乎 编辑:程序博客网 时间:2024/06/06 00:20

1.服务入门

进程的等级

  1. Foreground process(前台进程)

    应用程序,用户正在操作,activity的onresume方法被执行了,可以相应点击事件。
  2. Visible process (可视进程)

    应用程序的ui界面,用户还可以看到,但是不能操作了。
  3. Service process (服务进程)

    应用程序没有界面,但是有一个后台的服务还处于运行状态
  4. Background process(后台进程)

    应用程序没有服务处于运行状态,应用程序被最小化了,activity执行了onstop方法
  5. Empty process (空进程)

    没有任何组件运行,所有的activity都关闭了,任务栈清空了

进程与应用程序之间的关系: linux操作系统创建一个进程,这个进程负责运行dalvik虚拟机,Android的应用程序都是运行在dalvik虚拟机上的。

  • 进程的生命周期

    1、应用程序一启动的时候就创建了进程;2、当应用程序退出的时候进程并没有退出;    缓存,加快下次启动的速度3、只有手工停止这个进程,进程才会结束;操作系统尽量长时间的运行应用程序的进程,为了保证内从空间不被大量占用,它会按照进程的优先级,从低到高一级一级的杀死进程,直到内存空间被清理的差不多。

服务的特点

  • 服务的特点:

    服务被创建时调用onCreate、onStartCommand;服务只能被创建一次,可以开启多次onStartCommand;服务只能被停止一次; 没有onPause、onStop、onResume、onRestart方法,因为service没有界面,长期运行在后台。
  • 生命周期的方法:

    onCreate:服务被创建的时候调用这个方法;onStartCommand :开启服务onDestroy:销毁服务

一个简单的示例

1.启动一个service

//使用意图启动ServiceIntent intent = new Intent(MainActivity.this, MyService.class);startService(intent);

2.创建一个类继承Service

public class MyService extends Service {@Overridepublic IBinder onBind(Intent intent) {    return null;}//创建服务的时候调用@Overridepublic void onCreate() {    System.out.println("*****onCreate******");    super.onCreate();}//启动server    每次start都会调用一次@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {    System.out.println("*****onStartCommand******");    return super.onStartCommand(intent, flags, startId);}//手动停止程序后会终止服务,会调用onDestroy()方法@Overridepublic void onDestroy() {    System.out.println("*****onDestroy******");    super.onDestroy();}}

3.添清单文件中添加一个service

<service android:name="com.example.servicedemo.MyService"></service>

2.服务的两种开启方式

API

方式1

直接启停startService(intent);stopService(intent);

方式2

绑定服务的方式bindService(intent, conn, BIND_AUTO_CREATE);unbindService(conn);

例程

在一个程序里如果配置了某个服务,那么不管如何new,始终只有那一个服务。

public void click1(View v){    //click1和click2   每次创建service都是一个东西    说明一个服务开启了就只存在一份    Intent intent = new Intent(MainActivity.this, ServerDemo.class);    startService(intent);}public void click2(View v){    //click1和click2   每次创建service都是一个东西    说明一个服务开启了就只存在一份    Intent intent = new Intent(MainActivity.this, ServerDemo.class);    stopService(intent);}public void click3(View v){    Intent intent = new Intent(MainActivity.this, ServerDemo.class);    conn = new MyServiceConnection();    bindService(intent, conn, BIND_AUTO_CREATE);}public void click4(View v){    unbindService(conn);}//这里注意,使用bind的方法必须实现这个类,用于监控绑定状态private class MyServiceConnection implements ServiceConnection {    //绑定成功回调    @Override    public void onServiceConnected(ComponentName name, IBinder service) {       }    //解除绑定回调    @Override    public void onServiceDisconnected(ComponentName name) {             }   } 

3.使用绑定获取服务中的方法

绑定服务的应用场景

 应用场景: 1、需要在后台运行一定的业务逻辑,而且需要与服务器端交互数据,都是写在服务里面的。 2、天气预报、股票行情软件;

API

bindService绑定服务、unBindService解除绑定的服务;服务是在被绑定的时候被创建,调用oncreate、onbind方法;服务只能被绑定一次;服务只能被解除一次,接触绑定的时候调用onUnbind、onDestrory方法,如果多次解除绑定会抛出异常;推荐的方式(启用顺序):1.startService:开启并创建一个服务,服务长期运行在后台;2.bindService:绑定服务,可以调用服务里面的方法;3.unBindService:解除服务,停止服务里面的方法;4.stopService:停止服务,销毁服务对象;

例程

注意,我们需要在后台开启一个服务,这个服务一直在运行。可以通过前台调用后台服务中的函数,从而进行应用程序和服务交互。

startService(intent);方法可以创建一个服务,如果不手动关闭(假定操作系统没有回收这个服务),适用于创建一个后台服务。

bindService(intent, new MyServiceConnection(), BIND_AUTO_CREATE);方法用于绑定一个服务。在startService方法后调用。

1.MainActivity

public class MainActivity extends Activity {private MyBind serverRet;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    Intent intent = new Intent(MainActivity.this, BackgroundService.class);    startService(intent);    bindService(intent, new MyServiceConnection(), BIND_AUTO_CREATE);}public void click1(View v){    //调用服务的方法    serverRet.callPaly();}public void click2(View v){    serverRet.callPause();}public void click3(View v){    serverRet.callReplay();}class MyServiceConnection implements ServiceConnection{    @Override    public void onServiceConnected(ComponentName name, IBinder service) {        //返回服务中包含要调用方法的类        serverRet = (MyBind) service;    }    @Override    public void onServiceDisconnected(ComponentName name) {    }}}

Service

public class BackgroundService extends Service {@Overridepublic IBinder onBind(Intent intent) {    return new MyBind();     //返回到前台的对象,包含要执行的service中的方法}@Overridepublic void onCreate() {    super.onCreate();}@Overridepublic void onDestroy() {    super.onDestroy();}public void paly() {    System.out.println("********paly********");}public void pause() {    System.out.println("********pause********");}public void replay() {    System.out.println("********replay********");}//继承Binder类,这是因为要返回一个实现IBinder类型接口的    实现Iservice方法,这个接口里面的函数都是我们自己定义的要传给前台的函数public class MyBind extends Binder implements Iservice{    @Override    public void callPaly() {        paly();    }    @Override    public void callPause() {        pause();    }    @Override    public void callReplay() {        replay();    }}}

Iservice 接口中定义我们要传递的方法

public interface Iservice {    public void callPaly();    public void callPause();    public void callReplay();}

4.获取其他进程的服务的方法

1.接口需要修改,将后缀名改为aidl(android interface defination language),并将包含这个接口的包名拷贝,在客户端也创建一个这个名字的包,也把这个aidl文件拷贝过去。

package com.example.ipc_server;interface Iservice {    void callServerFun();}

2.服务端清单文件中配置service,由于是调用不同程序的服务,所以使用隐式意图。action的name是由我们自己指定,客户端在创建隐式intent时需要写入名字,就是这个字符串。

    <service android:name="com.example.ipc_server.MyServer">        <intent-filter>            <action android:name="com.example.ipc_server"/>        </intent-filter>    </service>

3.客户端

public class MainActivity extends Activity {private Intent intent;private ServiceConnection conn;private Iservice serviceRet;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    //开启意图    intent = new Intent();    intent.setAction("com.example.ipc_server");    //绑定服务    conn = new MyConn();    bindService(intent, conn, BIND_AUTO_CREATE);}public void click(View v){    try {        serviceRet.callServerFun();    } catch (RemoteException e) {        e.printStackTrace();    }}class MyConn implements ServiceConnection{    @Override    public void onServiceConnected(ComponentName name, IBinder service) {        System.out.println("*********启动服务**********");        serviceRet = Iservice.Stub.asInterface(service);    }    @Override    public void onServiceDisconnected(ComponentName name) {    }}}

5.使用服务注册监听器

两种注册类型的区别:静态注册是当程序关闭后,如果有广播发过来,还能启动程序动态注册的生命周期跟程序的生命周期是一样的,程序关闭后动态注册的广播是不能在接收到广播的动态注册的优点:在Android的广播机制中,动态注册的优先级高于静态注册的优先级,因此在必要情况下,我们需要动态注册广播接收器。静态注册的有点:动态注册广播接收器还有一个优点就是当用来注册广播的Activity关闭后,广播也就失效了,同时反映了静态注册广播的一个优势,就是无需担心广播接收器是否关闭,只要设备处于开启状态,广播接收器就能接收。  操作频繁的广播事件,如果只是在清单配置文件配置,是不生效的。需要使用代码注册才能生效; 步骤: // 注册广播接收者    // 1、得到广播接收者的对象    ScreenBroadCastReceiver screenReceiver = new ScreenBroadCastReceiver();    // 2、创建一个intentFilter对象    IntentFilter filter = new IntentFilter();    // 3、注册接收的事件类型    filter.addAction("android.intent.action.SCREEN_ON");    filter.addAction("android.intent.action.SCREEN_OFF");    // 4、注册广播接收者    this.registerReceiver(screenReceiver, filter);
2 0
原创粉丝点击