小谈Android四大组件之Service

理解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!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值