• Android -Services 使用简介


    Android Services 四大组件之一,主要用于后台长时间运行。没有界面。这里讲解两种services的启动还有AIDL通信方式。

    1.startservices

    a.建立继承services的类,复写方法(本地服务)

    public class MyServices extends Service  {
    
        private static final String TAG="TestTag";
    
        @Override
        public IBinder onBind(Intent arg0) {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public void onCreate() {
            Log.i(TAG, "onCreate");
            super.onCreate();
        }
    
        @Override
        public void onStart(Intent intent, int startId) {
            Log.i(TAG, "onStart");
            super.onStart(intent, startId);
        }
    
        @Override
        public void onDestroy() {
            Log.i(TAG, "onDestroy");
            super.onDestroy();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.i(TAG, "onStartCommand");
            return super.onStartCommand(intent, flags, startId);
        }
    
    }

    b.声明AndroidManifest

    <service android:name=".MyServices"/>

    c.启动关闭

    switch(v.getId()){
                    case R.id.btnStart:
                        startService(intent);
                        break;
                    case R.id.btnStop:
                        stopService(intent);
                        break;
      }

    后记:

    服务生命周期:context.startService() ->onCreate()- >onStart()- >onStartCommand()->Service running ->context.stopService()  ->onDestroy() ->Service stop

    如果Service还没有运行,则android先调用onCreate()然后调用onStartCommand(),每次调用startService(Intent)的时候,都会调用执行onStartCommand();
    如果Service已经运行,则只调用onStartCommand()。

    2.bindservices

    服务链接(ServiceConnection)或直接获取Service中状态和数据信息 
    服务链接能够获取Service的对象,因此绑定Service的组件可以调用Service中的实现的函数 
    使用Service的组件通过Context.bindService()建立服务链接,通过Context.unbindService()停止服务链接 
    如果在绑定过程中Service没有启动,Context.bindService()会自动启动Service 
    同一个Service可以绑定多个服务链接,这样可以同时为多个不同的组件提供服务

    a.创建BindService继承Service

    public class BindService extends Service {
    
        private static final String TAG="BindService";
    
        private BindServiceX myBinderServiceX=new BindServiceX();
        public class BindServiceX extends Binder{
            public BindService getBindService() {
                return BindService.this;
            }
        }
    
        @Override
        public IBinder onBind(Intent arg0) {
            // TODO Auto-generated method stub
            Log.i(TAG, "onBind");
            return myBinderServiceX;
        }
    
        @Override
        public void onCreate() {
            Log.i(TAG, "onCreate");
            super.onCreate();
        }
    
    
    
    
    
        @Override
        public boolean onUnbind(Intent intent) {
            Log.i(TAG, "onUnbind");
            return super.onUnbind(intent);
        }
    
        @Override
        public void onDestroy() {
            Log.i(TAG, "onDestroy");
            super.onDestroy();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.i(TAG, "onStartCommand");
            return super.onStartCommand(intent, flags, startId);
        }
    
        public void ShowLog(){
            Log.i(TAG, "BindService=>ShowLog");
        }
    
    }

    b.声明AndroidManifest

    <service android:name=".BindService"/>

    c.启动使用

    public void onClick(View v) {
                Intent intentBind = new Intent(MainActivity.this, BindService.class);
    
                switch (v.getId()) {
                    case R.id.btnStartBindService:
                        bindService(intentBind, conn, Context.BIND_AUTO_CREATE);
                        break;
                    case R.id.btnStopBindService:
                        if (isConn) {
                            unbindService(conn); //不可以多次调用
                            isConn=false;
                        }
                        break;
                }

    后记:

    AndroidServiceActivity绑定方法,Context.BIND_AUTO_CREATE表明只要绑定存在,就自动建立Service;同时也告知Android系统,这个Service的重要程度与调用者相同,除非考虑终止调用者,否则不要关闭这个Service。

    如果service没被创建,那么调用一次onCreate(),然后调用onBind(),多次绑定时,不会多次调用onBind()。

    通过unbindService()函数取消绑定Servcie时,onUnbind()函数将被调用, 
    如果onUnbind()函数的返回true,则表示在调用者绑定新服务时, 
    onRebind()函数将被调用

    取消绑定仅需要使用unbindService()方法,并将ServiceConnnection传递给unbindService()方法需注意的是,unbindService()方法成功后,系统并不会调用onServiceDisconnected(),因为onServiceDisconnected()仅在意外断开绑定时才被调用

    3.AIDL IPC通信 services

    Android系统中,各个应用都运行在自己的进程中,进程之间一般无法直接进行通信,为了实现进程通信(interprocess communication,简称IPC),android提供了AIDL Service;  

    Android需要AIDL(Android Interface Definition Language)来定义远程接口,这种接口定义语言并不是一种真正的变成语言,只是定义两个进程之间的通信接口 

    与Java接口相似,但是存在如下几点差异  

    • AIDL定义接口的源代码必须以.aidl结尾  

    • AIDL用到的数据类型,除了基本类型、String、List、Map、CharSequence之外,其它类型全部都需要导包,即使它们在同一个包中也需要导包; 

     AIDL的步骤:

    a.创建AIDL文件

    package com.example.zcx.servicesdemo;
    
    // Declare any non-default types here with import statements
    
    //interface ICat {
    //    /**
    //     * Demonstrates some basic types that you can use as parameters
    //     * and return values in AIDL.
    //     */
    //    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
    //            double aDouble, String aString);
    //}
    interface ICat {
        String getColor();
        double getWeight();
    }

    b.服务端编写

    public class AidlService extends Service {
        String[] colors = new String[] { "红色", "黄色", "黑色" };
        double[] weights = new double[] { 2.3, 3.1, 1.58 };
        private String color;
        private double weight;
        private CatBinder catBinder;
        Timer timer = new Timer();
    
        @Override
        public void onCreate() {
            super.onCreate();
            catBinder = new CatBinder();
            timer.schedule(new TimerTask() {
    
                @Override
                public void run() {
                    // 随机地改变service组件内的color,weight属性的值
                    int rand = (int) (Math.random() * 3);
                    color = colors[rand];
                    weight = weights[rand];
                    System.out.println("---------" + rand);
                }
            }, 0, 800);
        }
    
    
        @Override
        public IBinder onBind(Intent arg0) {
            /**
             * 返回CatBinder对象,在绑定本地Service情况下,
             * 该catBinder会直接传给客户端的ServiceConnected对象的ServiceConnected
             * ()方法的第二个参数;在绑定远程Service的情况下
             * ,只将catBinder对象的代理传给客户端的ServiceConnected对象的ServiceConnected()方法的第二个参数
             */
            return catBinder;
        }
    
        @Override
        public void onDestroy() {
            timer.cancel();
        }
    
        /**
         * 继承Stub,也就是实现了ICat接口,并实现了IBinder接口
         *
         * @author pengcx
         *
         */
        public class CatBinder extends ICat.Stub {
            @Override
            public String getColor() throws RemoteException {
                return color;
            }
    
            @Override
            public double getWeight() throws RemoteException {
                return weight;
            }
        }
    }

    androidmanifest:

    <service android:name=".AidlService" android:process=":remote">
                <intent-filter>
                    <action android:name="org.crazyit.aidl.AIDL_SERVICE" />
                </intent-filter>
    </service>

    c.客户端使用

    首先需要建立aidl,注意要在相同的包名下,否则报错: java.lang.SecurityException: Binder invocation to an incorrect interface

    // ICat.aidl
    package com.example.zcx.servicesdemo;
    
    // Declare any non-default types here with import statements
    
    //interface ICat {
    //    /**
    //     * Demonstrates some basic types that you can use as parameters
    //     * and return values in AIDL.
    //     */
    //    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
    //            double aDouble, String aString);
    //}
    interface ICat {
        String getColor();
        double getWeight();
    }

    编写客户端:

    public class MainActivity extends AppCompatActivity {
    
        private ICat catService;
        private Button getButton;
        private EditText colorEditText, weightEditText;
    
        private ServiceConnection conn = new ServiceConnection() {
            @Override
            public void onServiceDisconnected(ComponentName name) {
                catService = null;
            }
    
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                // 获取远程Service的onBinder方法返回的对象代理
                catService = ICat.Stub.asInterface(service);
                Log.d("zcx","catService");
            }
        };
        public static Intent getExplicitIntent(Context context, Intent implicitIntent) {
            // Retrieve all services that can match the given intent
            PackageManager pm = context.getPackageManager();
            List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);
            // Make sure only one match was found
            if (resolveInfo == null || resolveInfo.size() != 1) {
                return null;
            }
            // Get component info and create ComponentName
            ResolveInfo serviceInfo = resolveInfo.get(0);
            String packageName = serviceInfo.serviceInfo.packageName;
            String className = serviceInfo.serviceInfo.name;
            ComponentName component = new ComponentName(packageName, className);
            // Create a new intent. Use the old one for extras and such reuse
            Intent explicitIntent = new Intent(implicitIntent);
            // Set the component to be explicit
            explicitIntent.setComponent(component);
            return explicitIntent;
        }
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            getButton = (Button) findViewById(R.id.getbutton);
            colorEditText = (EditText) findViewById(R.id.coloredittext);
            weightEditText = (EditText) findViewById(R.id.weightedittext);
    
            // 创建所需要绑定的Service的Intent
            Intent intent = new Intent();
            intent.setAction("org.crazyit.aidl.AIDL_SERVICE");
            //intent.setPackage(getPackageName());
            Intent eintent = new Intent(getExplicitIntent(this,intent));
            Log.e("zcx","eintent = "+eintent);
            // 绑定远程的服务
            Log.e("zcx"," "+bindService(eintent, conn, Service.BIND_AUTO_CREATE));
    
            getButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // 获取并显示远程service的状态
                    try {
                        colorEditText.setText(catService.getColor());
                        weightEditText.setText(catService.getWeight() + "");
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            // 解除绑定
            this.unbindService(conn);
        }
    }
  • 相关阅读:
    【设计模式学习笔记】之 装饰者模式
    【实操笔记】MySQL主从同步功能实现
    Centos6.7安装mysql 5.6简单教程
    【转载备忘】PowerDesigner16.5基本使用
    win10安装配置jdk的环境变量
    eclipse配置虚拟路径后,每次启动tomcat都会虚拟路径失效的问题解决
    Tomcat配置虚拟路径访问容器外的硬盘资源
    编写代码常用快捷键
    python爬虫之scrapy框架介绍
    python面试题(一)
  • 原文地址:https://www.cnblogs.com/zCoderJoy/p/7062071.html
Copyright © 2020-2023  润新知