zoukankan      html  css  js  c++  java
  • Service

    Service相关
        a、Service的特点
            不可见、不可交互,在后台运行的四大组件之一。
              并不是所有的功能都需要界面。比如音乐播放。
        b、Service的启动方式
            startService、bindService
        c、Service的生命周期
            a、通过startService
                Service会经历 onCreate 到onStart,然后处于运行状态,stopService的时候调用onDestroy方法。
                这种方式,activity和service是相互独立的。如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行
            b、通过bindService
                Service会运行onCreate,然后是调用onBind, 这个时候调用者和Service绑定在一起。调用者解绑了,Service就会调用onUnbind->onDestroyed方法。
                  这种方式,activity就和service相互捆绑在一起了。所谓绑定在一起就共存亡了。调用者也可以通过调用unbindService方法来停止服务,这时候Service    会调用onUnbind-                    >onDestroyed方法。
            简单来说,startService的方式启动之后,Activity是调用不到Service里面的方法。
            bindService方式启动之后,可以得到Service的实例,进而调用Service里面的方法。startService和bindService可以结合使用。无论怎么结合,Service的实例只有一个。
        d、为什么使用Service
            普通的线程也可以达到在后台做事情的功能,那么为什么使用 Service呢?是因为Service是系统的组件,它的优先级比普通的线程要高,不容易被系统回收。而且线程不好控制,                service相对好控制一些。运行在前台的Activity是不会被系统回收的,而Service如果不想被系统回收,就需要在Service中设置一下startForeground(int,Notification)
            具体的使用场景有:
            a、拥有长连接QQ
            b、定时轮询
            c、服务里面注册广播接收者。有些广播接收者只能通过代码注册,比如屏幕锁屏、屏幕解锁、电量发生变化等。
        e、IntentService
            普通的service ,默认运行在ui main 主线程.Sdk给我们提供的方便的、带有异步处理的service类,我们可以在OnHandleIntent() 处理耗时的操作
          

    service的基本用法

    关于Service最基本的用法自然就是如何启动一个Service了,启动Service的方法和启动Activity很类似,都需要借助Intent来实现,下面我们就通过一个具体的例子来看一下。

    新建一个Android项目,项目名就叫ServiceTest,这里我选择使用4.0的API。

    然后新建一个MyService继承自Service,并重写父类的onCreate()、onStartCommand()和onDestroy()方法,如下所示:

    1. public class MyService extends Service {  
    2.   
    3.     public static final String TAG = "MyService";  
    4.   
    5.     @Override  
    6.     public void onCreate() {  
    7.         super.onCreate();  
    8.         Log.d(TAG, "onCreate() executed");  
    9.     }  
    10.   
    11.     @Override  
    12.     public int onStartCommand(Intent intent, int flags, int startId) {  
    13.         Log.d(TAG, "onStartCommand() executed");  
    14.         return super.onStartCommand(intent, flags, startId);  
    15.     }  
    16.       
    17.     @Override  
    18.     public void onDestroy() {  
    19.         super.onDestroy();  
    20.         Log.d(TAG, "onDestroy() executed");  
    21.     }  
    22.   
    23.     @Override  
    24.     public IBinder onBind(Intent intent) {  
    25.         return null;  
    26.     }  
    27.   
    28. }  

    可以看到,我们只是在onCreate()、onStartCommand()和onDestroy()方法中分别打印了一句话,并没有进行其它任何的操作。

    然后打开或新建activity_main.xml作为程序的主布局文件,代码如下所示:

    1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    2.     android:layout_width="match_parent"  
    3.     android:layout_height="match_parent"  
    4.     android:orientation="vertical" >  
    5.   
    6.     <Button  
    7.         android:id="@+id/start_service"  
    8.         android:layout_width="match_parent"  
    9.         android:layout_height="wrap_content"  
    10.         android:text="Start Service" />  
    11.   
    12.     <Button  
    13.         android:id="@+id/stop_service"  
    14.         android:layout_width="match_parent"  
    15.         android:layout_height="wrap_content"  
    16.         android:text="Stop Service" />  
    17.   
    18. </LinearLayout>  


    我们在布局文件中加入了两个按钮,一个用于启动Service,一个用于停止Service。

    然后打开或新建MainActivity作为程序的主Activity,在里面加入启动Service和停止Service的逻辑,代码如下所示:

    1. public class MainActivity extends Activity implements OnClickListener {  
    2.   
    3.     private Button startService;  
    4.   
    5.     private Button stopService;  
    6.   
    7.     @Override  
    8.     protected void onCreate(Bundle savedInstanceState) {  
    9.         super.onCreate(savedInstanceState);  
    10.         setContentView(R.layout.activity_main);  
    11.         startService = (Button) findViewById(R.id.start_service);  
    12.         stopService = (Button) findViewById(R.id.stop_service);  
    13.         startService.setOnClickListener(this);  
    14.         stopService.setOnClickListener(this);  
    15.     }  
    16.   
    17.     @Override  
    18.     public void onClick(View v) {  
    19.         switch (v.getId()) {  
    20.         case R.id.start_service:  
    21.             Intent startIntent = new Intent(this, MyService.class);  
    22.             startService(startIntent);  
    23.             break;  
    24.         case R.id.stop_service:  
    25.             Intent stopIntent = new Intent(this, MyService.class);  
    26.             stopService(stopIntent);  
    27.             break;  
    28.         default:  
    29.             break;  
    30.         }  
    31.     }  
    32.   
    33. }  

    可以看到,在Start Service按钮的点击事件里,我们构建出了一个Intent对象,并调用startService()方法来启动MyService。然后在Stop Serivce按钮的点击事件里,我们同样构建出了一个Intent对象,并调用stopService()方法来停止MyService。代码的逻辑非常简单,相信不需要我再多做解释了吧。

    另外需要注意,项目中的每一个Service都必须在AndroidManifest.xml中注册才行,所以还需要编辑AndroidManifest.xml文件,代码如下所示:

    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     package="com.example.servicetest"  
    4.     android:versionCode="1"  
    5.     android:versionName="1.0" >  
    6.   
    7.     <uses-sdk  
    8.         android:minSdkVersion="14"  
    9.         android:targetSdkVersion="17" />  
    10.   
    11.     <application  
    12.         android:allowBackup="true"  
    13.         android:icon="@drawable/ic_launcher"  
    14.         android:label="@string/app_name"  
    15.         android:theme="@style/AppTheme" >  
    16.           
    17.     ……  
    18.   
    19.         <service android:name="com.example.servicetest.MyService" >  
    20.         </service>  
    21.     </application>  
    22.   
    23. </manifest>  



    这样的话,一个简单的带有Service功能的程序就写好了,现在我们将程序运行起来,并点击一下Start Service按钮,可以看到LogCat的打印日志
                                                 

    也就是说,当启动一个Service的时候,会调用该Service中的onCreate()和onStartCommand()方法。

    那么如果我再点击一次Start Service按钮呢?这个时候的打印日志如下:           

    可以看到,这次只有onStartCommand()方法执行了,onCreate()方法并没有执行,为什么会这样呢?

    这是由于onCreate()方法只会在Service第一次被创建的时候调用,如果当前Service已经被创建过了,不管怎样调用startService()方法,onCreate()方法都不会再执行。因此你可以再多点击几次Start Service按钮试一次,每次都只会有onStartCommand()方法中的打印日志。

    我们还可以到手机的应用程序管理界面来检查一下MyService是不是正在运行,如下图所示:

                                             

    恩,MyService确实是正在运行的,即使它的内部并没有执行任何的逻辑。

    回到ServiceTest程序,然后点击一下Stop Service按钮就可以将MyService停止掉了。

  • 相关阅读:
    Python使用Django创建第一个项目
    如何使用RobotFramework编写好的测试用例
    接口测试 总结(什么是接口测试)
    APP接口测试
    Django基础五之中间件
    Django基础五之django模型层(二)多表操作
    Django基础五之django模型层(一)单表操作
    Django基础四之模板系统
    Django基础三之视图函数
    DJANGO2--url路由
  • 原文地址:https://www.cnblogs.com/zyanrong/p/5413360.html
Copyright © 2011-2022 走看看