原创 Android之Service的简单实例

2021-10-14 12:14 1931 17 17 分类: 软件与OS 文集: android studio

通过前面的学习,读者应该对Service有了一个全面的了解,也知道了创建与启动Service的具体步骤与方法。下面将通过实例带领大家一起学习如何使用Service

实例:以start方式创建与启动Service

通过前面的学习,我们知道了用start方式创建以及使用 Service4个步骤,下面我们按照这4个步骤来进行讲解。

1 创建一个继承 Service 的类 MyService,在类中实现它的几个主要方法,为了验证生命周期的结论,我们在生命周期方法中都加入了Log。同时,为了模拟真实的开发环境,我们建立了一个线程,并在onStartCommand(Intent intentin flagsin startld)方法中使用这个线程,在onDestroy()挂起线程,并销毁线程对象。具体的代码如下;

  1. package com.rfstar.servicetest01;
  2. import android.app.Service;
  3. import android.content.Intent;
  4. import android.os.IBinder;
  5. import android.util.Log;
  6. import androidx.annotation.Nullable;
  7. public class MyService extends Service {
  8. private Thread thread;
  9. private ServiceThread serviceThread;
  10. @Override
  11. public void onCreate()
  12. {
  13. super.onCreate();
  14. Log.i("MyService","onCreate");
  15. }
  16. @Override
  17. public int onStartCommand(Intent intent,int flags,int startId)
  18. {
  19. Log.i("MyService","onStartCommand");
  20. serviceThread=new ServiceThread();
  21. thread=new Thread(serviceThread);
  22. //开启一个线程
  23. thread.start();
  24. return super.onStartCommand(intent,flags,startId);
  25. }
  26. @Override
  27. public void onDestroy()
  28. {
  29. super.onDestroy();
  30. //结束run方法的循环
  31. serviceThread.flag=false;
  32. //挂起线程
  33. thread.interrupt();
  34. thread=null;
  35. Log.i("MyService","onDestroy");
  36. }
  37. @Nullable
  38. @Override
  39. public IBinder onBind(Intent intent)
  40. {
  41. Log.i("MyService","onBind");
  42. return null;
  43. }
  44. @Override
  45. public boolean onUnbind(Intent intent)
  46. {
  47. Log.i("MyService","onUnbind");
  48. return super.onUnbind(intent);
  49. }
  50. class ServiceThread implements Runnable
  51. {
  52. //用volatile修饰保证变量在线程间的可见性
  53. volatile boolean flag=true;
  54. @Override
  55. public void run() {
  56. while (flag)
  57. {
  58. try{
  59. //间隔1秒
  60. Thread.sleep(1000);
  61. } catch (InterruptedException exception) {
  62. Log.i("MyService",exception.toString());
  63. }
  64. Log.i("MyService","thread正在进行");
  65. }
  66. }
  67. }
  68. }

2  AndroidManifest.xml 中配置 Service。在讲解Activity 时,我们讲解了显式意图和隐式意图的概念,不同形式的意图在AndroidManifest.xml中需要进行不同的配置,而且我们还解释了为何多使用隐式意图的方式进行Activity间跳转。这里特别说明一下,虽然在 Service 中也存在这样两种形式的意图,但是由于在Android 5.0之后Google公司出于安全考虑,禁止了隐式声明 Intent来启动Service。因此,在开发中建议只使用显式意图,配置如下(为防止一些新入门的读者放错位置,展示出全部配置文件):

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.rfstar.servicetest01">
  4. <application
  5. android:allowBackup="true"
  6. android:icon="@mipmap/ic_launcher"
  7. android:label="@string/app_name"
  8. android:roundIcon="@mipmap/ic_launcher_round"
  9. android:supportsRtl="true"
  10. android:theme="@style/AppTheme">
  11. <activity android:name=".MainActivity">
  12. <intent-filter>
  13. <action android:name="android.intent.action.MAIN" />
  14. <category android:name="android.intent.category.LAUNCHER" />
  15. </intent-filter>
  16. </activity>
  17. <!--加入这样一条配置即可-->
  18. <service android:name=".MyService"></service>
  19. </application>
  20. </manifest>

3 通过 Context 调用 startServiceIntent intent)方法来开启 Service,调用 stopServieIntent intent)方法来终止 Service。为了实现这样的目的,我们在Activity 中使用两个按钮来分别负责Service 的开启和终止。当然这只是一个实例,在开发实践中如何使用 Service是十分灵活的,读者在开发时可以根据具体的需要来决定如何开启与终止 Service。实例代码如下所示。

MainActivity的布局文件activity_main.xml代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:orientation="vertical"
  8. tools:context=".MainActivity">
  9. <Button
  10. android:id="@+id/startService"
  11. android:layout_width="match_parent"
  12. android:layout_height="wrap_content"
  13. android:text="start service"
  14. android:textSize="25sp"/>
  15. <Button
  16. android:id="@+id/stopService"
  17. android:layout_width="match_parent"
  18. android:layout_height="wrap_content"
  19. android:text="stop service"
  20. android:textSize="25sp"/>
  21. </LinearLayout>

MainActivity代码如下:

  1. package com.rfstar.servicetest01;
  2. import androidx.appcompat.app.AppCompatActivity;
  3. import android.content.Intent;
  4. import android.os.Bundle;
  5. import android.view.View;
  6. import android.widget.Button;
  7. public class MainActivity extends AppCompatActivity implements View.OnClickListener{
  8. private Button startButton;
  9. private Button stopButton;
  10. @Override
  11. protected void onCreate(Bundle savedInstanceState) {
  12. super.onCreate(savedInstanceState);
  13. setContentView(R.layout.activity_main);
  14. initView();
  15. }
  16. private void initView()
  17. {
  18. startButton=(Button)findViewById(R.id.startService);
  19. stopButton=(Button)findViewById(R.id.stopService);
  20. startButton.setOnClickListener(this);
  21. stopButton.setOnClickListener(this);
  22. }
  23. @Override
  24. public void onClick(View view) {
  25. switch (view.getId())
  26. {
  27. case R.id.startService:
  28. //创建意图
  29. Intent startIntent=new Intent(this,MyService.class);
  30. //开启Service
  31. startService(startIntent);
  32. break;
  33. case R.id.stopService:
  34. //创建意图
  35. Intent stopIntent=new Intent(this,MyService.class);
  36. // 终止服务
  37. stopService(stopIntent);
  38. break;
  39. }
  40. }
  41. }

Activity 中对Button 按钮的点击事件进行了监听,并在点击时分别开启服务和终止服务。运行程序,效果如下图所示。

此时,点击"START SERVICE"按钮,观察Log 的输出,发现 Service 以及Service中的线程确实被开启了,Log如下

当点击"STOP SERVICE"按钮时,观察Log的输出,发现Thread不再运行,Service也被终止了,Log如下

从输出的Log中还可以清晰看出以start方式开启的Service的生命周期恰是上一章所阐的那样,它的生命周期方法是按照 onCreate()→onStartCommand()→Service running——调用context.stopServce()→onDestroy()这样一条路径运行的。

此时如果开启了服务,但是并没有终止服务就直接退出程序,服务是不会被终止的,大家用上面的实例可以亲手进行测试。所以当开启服务之后,它是不会自己停止的,也不会随开启者的销毁而销毁,所以一定要调用stopService()方法来终止它,至于终止的时机需要根据具体的业务来把握。

android studio工具及手机模拟器以及更多工程源代码下载请前往微信公众号:大鸟科创空间,回复:android studio即可获取。

作者: 大鸟科创空间, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-3949041.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

文章评论0条评论)

登录后参与讨论
我要评论
0
17
关闭 站长推荐上一条 /2 下一条