小谈Android四大组件之Service

来源:互联网 发布:仙侠学院 2网络电影 编辑:程序博客网 时间:2024/06/14 19:26

理解Service

*windows中: 长期后台运行没有界面的进程就叫服务
*Android中: 运行在当前应用程序进程里面,长期后台运行,没有界面的组件.
*创建的时候也需要在清单文件里注册

PS:Service的父类是Activity的父类的父类,可以说Service是Activity的叔!!!

**

应用场景

**
一个特殊的没有界面的,可长期执行的”Activity”

1.比如,监测一个硬件是否被插入
2.连接服务器刷新最新的数据
3.定时轮询(开启子线程轮询. 轮询条件用flag控制)

注意:

1.服务运行在主线程里面,不可以直接在服务里面编写耗时的逻辑.需要开启子线程进行操作.2.开启服务. startService(intent);3.停止服务. stopService(intent); 停止服务时用flag=false控制

Service的生命周期

这里写图片描述

这个图中将开启的Service 和绑定的Service 分开,但是我们需要记住,任何Service 都潜在地允许被绑定。所以,一个被开启的Service 仍然可能被绑定。实现这些方法,可以看到两层嵌套的Service 的生命周期。

进程的优先级

*Foreground process

前台进程:用户正在操作的进程

*Visible process

可视进程:用户已经不能操作这个应用程序了,但是界面用户任然可以看到

*Service process

服务进程: 应用程序有一个服务代码正在运行.
注: 即使进程被回收,只要当内存充足时,service会被系统自动复活.

*Background process

后台进程: 应用程序有界面,但是界面被用户最小化(按home)

*Empty process

空进程: 应用程序没有任何运行的Activity, service.

优先级: 从上到下,依次减小
前台>可视>服务>后台>空进程

如何开启Service

一, 直接开启(标准开启模式) A Started Service

*在Activity中调用startService()方法创建,必须调用stopSelf()方法或者其他组件调用stopService()方法来停止它.*缺点:在Activity里面直接调用Service里面的方法,是行不通的. 不可以与服务进行通信.

二,绑定开启(绑定模式) A Bound Service

原理: 直接调用不行,找一个Service的内部类去间接调用服务内部的方法.**调用bindService()来创建的,可以通过一个IBinder接口和service 进行通信.通过unbindService()方法来关闭这种连接.**一个service 可以同时和多个Activity绑定,当多个客户都解除绑定之后,系统会销毁service.

三,混合的方式开启服务

严格按照步骤编写代码1.start的方式开启服务(保证服务长期在后台运行)2.bind 绑定服务(调用服务的方法)3.unbind的方式解除绑定服务   4.stop  停止服务

说了这么多,该来真东西了,直接上案例~~

<案例一: 绑定开启Service,找有关部门办暂住证>

需求:
模拟某人(Activity)需要办一个暂住证,直接找有关部门(Service)很难办成,但是通过一个中介(Service内部类)给点手续费,就水到渠成的办成了!!

步骤:

1.创建一个CertificateService类继承Service,重写onBind()方法, 配置清单文件.

public class CertificateService extends Service {    @Override    public IBinder onBind(Intent intent) {        System.out.println("onBind");        //返回一个中间人(中介)        return new MyBinder();    }    //Service内部的方法,Activity不能直接访问    public void methodInService(String name){        System.out.println("我是服务里的方法,我被调用了");        Toast.makeText(CertificateService.this, name+"您好!您的暂住证已经办好...", 0).show();    }    /**    *内部类. 即中间人.     *IService是事先创建好的一个Interface, 只有一个方法callMethodInService().    */    private class MyBinder extends Binder implements IService{        @Override        public void callMethodInService(String name, int money) {            if (money>200) {                methodInService(name);            }else {                Toast.makeText(CertificateService.this, "对不起,我们这里得按制度办事...", 0).show();            }        }    }}

2.在MainActivity里通过中间人MyBinder调用Service里的方法MethodInService().

public class MainActivity extends Activity {    private IService iService;    private MyConn conn;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    /**     * 绑定服务代理     * @param view     */    public void bind(View view){        Intent intent = new Intent(MainActivity.this,CertificateService.class);        conn=new MyConn();        bindService(intent, conn, BIND_AUTO_CREATE);    }    /**     * 通过代理调用服务里的方法     * @param view     */    public void call(View view){        iService.callMethodInService("歪歪", 300);    }    /**     * 解除绑定     * @author Administrator     *     */    public void unBind(View view){        unbindService(conn);    }    /**     * 内部类,用于连接Activity和中间人     * @author Administrator     *     */    public class MyConn implements ServiceConnection{        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            iService=(IService)service;        }        @Override        public void onServiceDisconnected(ComponentName name) {        }    }

3.Activity的布局如下:

线性布局

<LinearLayout 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:orientation="vertical"    tools:context=".MainActivity" >    <Button         android:onClick="bind"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="绑定中介"        />    <Button         android:onClick="call"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="开始办证"        /</LinearLayout>

<案例二: AIDL远程服务: 一个程序调用另一个程序的功能>

1.创建一个Service所在的项目,键一个IService接口,写好callMethodInService()方法后将其改成IService.aidl格式文件.
具体代码:

package com.heima.wechat;interface IService {    void callMethodInService();}

这里写图片描述

2.根据以上目录结构写好weChatService.
代码:

public class weChatService extends Service {    //内部类,重写IService里的方法    private class MyBinder extends IService.Stub {        @Override        public void callMethodInService() throws RemoteException {            methodInService();        }    }    @Override    public IBinder onBind(Intent intent) {        return new MyBinder();    }    @Override    public void onCreate() {        System.out.println("微信被开启了...");        super.onCreate();    }    public void methodInService() {        System.out.println("我是微信的摇一摇方法,我被调用了");    }    @Override    public void onDestroy() {        System.out.println("微信被关闭了...");        super.onDestroy();    }}

3.把远程服务IService.aidl文件拷贝到本地应用程序(远程访问)的工程目录里面,包名保持一致.

这里写图片描述

4.按以上目录,编写MainActivity的代码

如下:

public class MainActivity extends Activity {    private IService iservice;    private MyConn conn;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        conn=new MyConn();    }    public class MyConn implements ServiceConnection{        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            System.out.println("哈哈,绑定到了微信..");            //获取中间人对象            iservice=IService.Stub.asInterface(service);        }        @Override        public void onServiceDisconnected(ComponentName name) {        }    }    //绑定到Service    public void bind(View v){        Intent intent=new Intent();        intent.setAction("com.heima.wechat");        bindService(intent, conn, BIND_AUTO_CREATE);    }    //通过中间人调用Service里的方法    public void call(View v){        try {            iservice.callMethodInService();        } catch (RemoteException e) {            e.printStackTrace();        }    }}

5.远程访问的布局

<LinearLayout 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:orientation="vertical"    tools:context=".MainActivity" >    <Button        android:onClick="bind"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="绑定远程服务" />    <Button        android:onClick="call"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="分享到微信" /></LinearLayout>

AIDL运行结果如下:

这里写图片描述

系统服务

所有的系统服务都是同一个API, getSystemServices() 适用于Application Framework层所有的XXXManager

完了~~

Android四大组件已更新完, 希望可以和朋友们共同探讨,共同进步~~~Peace!

1 0