zoukankan      html  css  js  c++  java
  • Android中的service

    1.service简介:service可以在和多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务嘛,总是藏在后头的。Service是在一段不定的时间运行在后台,不和用户交互应用组件。每个Service必须在manifest中 通过<service>来声明。可以通过context.startservice和context.bindserverice来启动。

    2.Service的启动的两种方式:

      a.使用context.startService() 启动Service(本地服务 Local Service 用于应用程序内部)

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

    特点:使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。

    其生命周期为context.startService() ->onCreate()- >onStart(可多次调用)->Service running-->context.stopService()  ->onDestroy() ->Service stop 
    在这种方式下,它以调用Context.startService()启动,而以调用Context.stopService()结束。它可以调用Service.stopSelf() 或 Service.stopSelfResult()来自己停止。不论调用了多少次startService()方法,你只需要调用一次stopService()来停止服务。
    所以调用startService的生命周期为:onCreate --> onStart(可多次调用) --> onDestroy

    b.对于bindService()启动Service()

    目的:用于远程服务 Remote Service 用于android系统内部的应用程序之间。比如天气预报服务。

    特点:调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。
    其生命周期为context.bindService()->onCreate()->onBind()->Service running-->onUnbind() -> onDestroy() ->Service stop
    onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。
    这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind->onDestroy相应退出。 
    所以调用bindService的生命周期为:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。
    3.拥有service进程的优先级往往高一些

    官方文档告诉我们,Android系统会尽量保持拥有service的进程运行,只要在该service已经被启动(start)或者客户端连接(bindService)到它。当内存不足时,需要保持,拥有service的进程具有较高的优先级。

    • 如果service正在调用onCreate,onStartCommand或者onDestory方法,那么用于当前service的进程则变为前台进程以避免被killed。
    • 如果当前service已经被启动(start),拥有它的进程则比那些用户可见的进程优先级低一些,但是比那些不可见的进程更重要,这就意味着service一般不会被killed.
    • 如果客户端已经连接到service (bindService),那么拥有Service的进程则拥有最高的优先级,可以认为service是可见的。
    • 如果service可以使用startForeground(int, Notification)方法来将service设置为前台状态,那么系统就认为是对用户可见的,并不会在内存不足时killed。

    4.service是一个线程还是一个进程:

    答案都不是,因为service是长期的,而进程是短期的。service是在主进程中被开启的。当主进程退出,而service还在服务。进程就好比一个送快递的小哥,而service就好比你收到的那个快递。小哥人走了,你还是可以看这本书很久的啊。

    5.Service与Activity通信:

    Service后端的数据最终还是要呈现在前端Activity之上的,因为启动Service时,系统会重新开启一个新的进程,这就涉及到不同进程间通信的问题了(AIDL)这一节我不作过多描述,当我们想获取启动的Service实例时,我们可以用到bindService和onBindService方法,它们分别执行了Service中IBinder()和onUnbind()方法。

     为了让大家 更容易理解,我写了一个简单的Demo,大家可以模仿着我,一步一步的来。

     第一步:新建一个Android工程,我这里命名为ServiceDemo.

    第二步:修改main.xml代码,我这里增加了四个按钮,代码如下:

    <?xml version="1.0" encoding="utf-8"?>  
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
        android:orientation="vertical"  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent"  
        >  
        <TextView  
            android:id="@+id/text"    
            android:layout_width="fill_parent"   
            android:layout_height="wrap_content"   
            android:text="@string/hello"  
            />  
        <Button  
            android:id="@+id/startservice"  
            android:layout_width="fill_parent"  
            android:layout_height="wrap_content"  
            android:text="startService"  
        />  
        <Button  
            android:id="@+id/stopservice"  
            android:layout_width="fill_parent"  
            android:layout_height="wrap_content"  
            android:text="stopService"  
        />  
        <Button  
            android:id="@+id/bindservice"  
            android:layout_width="fill_parent"  
            android:layout_height="wrap_content"  
            android:text="bindService"  
        />  
        <Button  
            android:id="@+id/unbindservice"  
            android:layout_width="fill_parent"  
            android:layout_height="wrap_content"  
            android:text="unbindService"  
        />  
    </LinearLayout>  

    第三步:新建一个Service,命名为MyService.java代码如下:

    package com.tutor.servicedemo;  
    import android.app.Service;  
    import android.content.Intent;  
    import android.os.Binder;  
    import android.os.IBinder;  
    import android.text.format.Time;  
    import android.util.Log;  
    public class MyService extends Service {  
        //定义个一个Tag标签  
        private static final String TAG = "MyService";  
        //这里定义吧一个Binder类,用在onBind()有方法里,这样Activity那边可以获取到  
        private MyBinder mBinder = new MyBinder();  
        @Override  
        public IBinder onBind(Intent intent) {  
            Log.e(TAG, "start IBinder~~~");  
            return mBinder;  
        }  
        @Override  
        public void onCreate() {  
            Log.e(TAG, "start onCreate~~~");  
            super.onCreate();  
        }  
          
        @Override  
        public void onStart(Intent intent, int startId) {  
            Log.e(TAG, "start onStart~~~");  
            super.onStart(intent, startId);   
        }  
          
        @Override  
        public void onDestroy() {  
            Log.e(TAG, "start onDestroy~~~");  
            super.onDestroy();  
        }  
          
          
        @Override  
        public boolean onUnbind(Intent intent) {  
            Log.e(TAG, "start onUnbind~~~");  
            return super.onUnbind(intent);  
        }  
          
        //这里我写了一个获取当前时间的函数,不过没有格式化就先这么着吧  
        public String getSystemTime(){  
              
            Time t = new Time();  
            t.setToNow();  
            return t.toString();  
        }  
          
        public class MyBinder extends Binder{  
            MyService getService()  
            {  
                return MyService.this;  
            }  
        }  
    } 

    第四步:修改ServiceDemo.java,代码如下:

    package com.tutor.servicedemo;  
    import android.app.Activity;  
    import android.content.ComponentName;  
    import android.content.Context;  
    import android.content.Intent;  
    import android.content.ServiceConnection;  
    import android.os.Bundle;  
    import android.os.IBinder;  
    import android.view.View;  
    import android.view.View.OnClickListener;  
    import android.widget.Button;  
    import android.widget.TextView;  
    public class ServiceDemo extends Activity implements OnClickListener{  
         
        private MyService  mMyService;  
        private TextView mTextView;  
        private Button startServiceButton;  
        private Button stopServiceButton;  
        private Button bindServiceButton;  
        private Button unbindServiceButton;  
        private Context mContext;  
          
        //这里需要用到ServiceConnection在Context.bindService和context.unBindService()里用到  
        private ServiceConnection mServiceConnection = new ServiceConnection() {  
            //当我bindService时,让TextView显示MyService里getSystemTime()方法的返回值   
            public void onServiceConnected(ComponentName name, IBinder service) {  
                // TODO Auto-generated method stub  
                mMyService = ((MyService.MyBinder)service).getService();  
                mTextView.setText("I am frome Service :" + mMyService.getSystemTime());  
            }  
              
            public void onServiceDisconnected(ComponentName name) {  
                // TODO Auto-generated method stub  
                  
            }  
        };  
        public void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.main);  
            setupViews();  
        }  
          
        public void setupViews(){  
          
            mContext = ServiceDemo.this;  
            mTextView = (TextView)findViewById(R.id.text);  
              
              
              
            startServiceButton = (Button)findViewById(R.id.startservice);  
            stopServiceButton = (Button)findViewById(R.id.stopservice);  
            bindServiceButton = (Button)findViewById(R.id.bindservice);  
            unbindServiceButton = (Button)findViewById(R.id.unbindservice);  
              
            startServiceButton.setOnClickListener(this);  
            stopServiceButton.setOnClickListener(this);  
            bindServiceButton.setOnClickListener(this);  
            unbindServiceButton.setOnClickListener(this);  
        }  
         
        public void onClick(View v) {  
            // TODO Auto-generated method stub  
            if(v == startServiceButton){  
                Intent i  = new Intent();  
                i.setClass(ServiceDemo.this, MyService.class);  
                mContext.startService(i);  
            }else if(v == stopServiceButton){  
                Intent i  = new Intent();  
                i.setClass(ServiceDemo.this, MyService.class);  
                mContext.stopService(i);  
            }else if(v == bindServiceButton){  
                Intent i  = new Intent();  
                i.setClass(ServiceDemo.this, MyService.class);  
                mContext.bindService(i, mServiceConnection, BIND_AUTO_CREATE);  
            }else{  
                mContext.unbindService(mServiceConnection);  
            }  
        }  
          
          
          
    } 

    第五步:修改AndroidManifest.xml代码(将我们新建的MyService注册进去如下代码第14行:) 

    <?xml version="1.0" encoding="utf-8"?>  
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
          package="com.tutor.servicedemo"  
          android:versionCode="1"  
          android:versionName="1.0">  
        <application android:icon="@drawable/icon" android:label="@string/app_name">  
            <activity android:name=".ServiceDemo"  
                      android:label="@string/app_name">  
                <intent-filter>  
                    <action android:name="android.intent.action.MAIN" />  
                    <category android:name="android.intent.category.LAUNCHER" />  
                </intent-filter>  
            </activity>  
            <service android:name=".MyService" android:exported="true"></service>  
        </application>  
        <uses-sdk android:minSdkVersion="7" />  
    </manifest>   
  • 相关阅读:
    html中的块级元素、行内元素
    ptyhon_opencv 图像的基本操作
    正则表达式总结 2017.1.6
    HashMap 中的 entrySet()使用方法 2016.12.28
    (转)Redis持久化的几种方式
    负数与二进制换转方法
    (转)2019JAVA面试题附答案(长期更新)
    Java后端技术面试汇总(第一套)
    (转)Dubbo服务暴露过程源码分析
    Dubbo消费方服务调用过程源码分析
  • 原文地址:https://www.cnblogs.com/hupp/p/4801346.html
Copyright © 2011-2022 走看看