当前位置: 首页 > java >正文

启动式service

【实验目的】

充分理解Service的作用,与Activity之间的区别,掌握Service的生命周期以及对应函数,了解Service的主线程性质;掌握主线程的界面刷新的设计原则,掌握启动service的方式,及其工作原理;

【实验内容】

任务1:在service中实现随机数产生;

任务2:在Activity界面实现随机数的显示,并采用启动式完成service的启动;

【实验要求】

1、在service中实现随机数产生;

2、实现Service中的各个生命周期函数,并理解其功能;

2、在Activity界面实现随机数的显示,每2秒更新一次;

3、采用启动式完成service的启动;

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.service">
  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/Theme.MyApplication">
  11.         <activity
  12.             android:name=".MainActivity"
  13.             android:exported="true"> <!-- 明确设置exported属性 -->
  14.             <intent-filter>
  15.                 <action android:name="android.intent.action.MAIN" />
  16.                 <category android:name="android.intent.category.LAUNCHER" />
  17.             </intent-filter>
  18.         </activity>
  19.         <service android:name=".RandomNumberService" />
  20.     </application>
  21. </manifest>

MainActivity.java

  1. package com.example.service;
  2. import android.content.ComponentName;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.content.ServiceConnection;
  6. import android.os.Bundle;
  7. import android.os.Handler;
  8. import android.os.IBinder;
  9. import android.widget.TextView;
  10. import androidx.appcompat.app.AppCompatActivity;
  11. public class MainActivity extends AppCompatActivity {
  12.     private TextView randomTextView; // 用于显示随机数的TextView
  13.     private RandomNumberService service; // RandomNumberService的实例
  14.     private boolean isBound = false// 标记服务是否已绑定
  15.     // Handler用于定时更新UI
  16.     private final Handler handler = new Handler();
  17.     // Runnable对象,用于更新UI
  18.     private final Runnable runnable = new Runnable() {
  19.         @Override
  20.         public void run() {
  21.             if (isBound) {
  22.                 // 如果服务已绑定,则获取随机数并更新UI
  23.                 int randomNumber = service.getRandomNumber();
  24.                 randomTextView.setText(String.valueOf(randomNumber));
  25.             }
  26.             // 每2秒执行一次此Runnable
  27.             handler.postDelayed(this2000);
  28.         }
  29.     };
  30.     // ServiceConnection对象,用于绑定和解绑服务
  31.     private ServiceConnection connection = new ServiceConnection() {
  32.         @Override
  33.         public void onServiceConnected(ComponentName className, IBinder serviceBinder) {
  34.             RandomNumberService.RandomNumberBinder binder = (RandomNumberService.RandomNumberBinder) serviceBinder;
  35.             service = binder.getService();
  36.             isBound = true;
  37.             // 服务绑定后立即更新UI
  38.             handler.post(runnable);
  39.         }
  40.         @Override
  41.         public void onServiceDisconnected(ComponentName arg0) {
  42.             isBound = false;
  43.         }
  44.     };
  45.     @Override
  46.     protected void onCreate(Bundle savedInstanceState) {
  47.         super.onCreate(savedInstanceState);
  48.         setContentView(R.layout.activity_main);
  49.         randomTextView = findViewById(R.id.randomTextView);
  50.         // 绑定服务
  51.         Intent intent = new Intent(this, RandomNumberService.class);
  52.         bindService(intent, connection, Context.BIND_AUTO_CREATE);
  53.         // 启动服务
  54.         startService(intent);
  55.     }
  56.     @Override
  57.     protected void onDestroy() {
  58.         super.onDestroy();
  59.         // 解绑服务
  60.         if (isBound) {
  61.             unbindService(connection);
  62.             isBound = false;
  63.         }
  64.         handler.removeCallbacks(runnable); // 移除Runnable,避免内存泄漏
  65.     }
  66. }

RandomNumberService.java

  1. package com.example.service;
  2. import android.app.Service;
  3. import android.content.Intent;
  4. import android.os.Binder;
  5. import android.os.IBinder;
  6. import android.os.Handler;
  7. public class RandomNumberService extends Service {
  8.     private final IBinder binder = new RandomNumberBinder(); // Binder对象,用于Activity与Service通信
  9.     private int randomNumber; // 存储随机数
  10.     private Handler handler; // Handler对象,用于定时任务
  11.     @Override
  12.     public void onCreate() {
  13.         super.onCreate();
  14.         handler = new Handler();
  15.         // 在服务创建时生成一个随机数
  16.         generateRandomNumber();
  17.     }
  18.     @Override
  19.     public int onStartCommand(Intent intent, int flags, int startId) {
  20.         // 重启定时任务以生成新的随机数
  21.         restartTimer();
  22.         return START_STICKY;
  23.     }
  24.     @Override
  25.     public IBinder onBind(Intent intent) {
  26.         // 返回Binder对象,允许Activity绑定到Service
  27.         return binder;
  28.     }
  29.     public int getRandomNumber() {
  30.         // 提供一个方法供Activity获取当前的随机数
  31.         return randomNumber;
  32.     }
  33.     // 生成随机数的方法
  34.     private void generateRandomNumber() {
  35.         randomNumber = (int) (Math.random() * 100) + 1;
  36.     }
  37.     // 定时任务,每两秒生成一个新的随机数
  38.     private void startTimer() {
  39.         handler.postDelayed(new Runnable() {
  40.             @Override
  41.             public void run() {
  42.                 generateRandomNumber();
  43.                 startTimer(); // 递归调用以保持周期性
  44.             }
  45.         }, 2000);
  46.     }
  47.     // 重启定时任务
  48.     private void restartTimer() {
  49.         handler.removeCallbacksAndMessages(null); // 移除所有回调和消息
  50.         startTimer(); // 重新开始定时任务
  51.     }
  52.     // Binder内部类,用于Activity与Service通信
  53.     public class RandomNumberBinder extends Binder {
  54.         public RandomNumberService getService() {
  55.             // 返回Service的实例
  56.             return RandomNumberService.this;
  57.         }
  58.     }
  59.     @Override
  60.     public void onDestroy() {
  61.         super.onDestroy();
  62.         handler.removeCallbacksAndMessages(null); // 服务销毁时移除所有回调和消息
  63.     }
  64. }

activity_main.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="match_parent"
  4.     android:layout_height="match_parent">
  5.     <TextView
  6.         android:id="@+id/randomTextView"
  7.         android:layout_width="wrap_content"
  8.         android:layout_height="wrap_content"
  9.         android:text="Random Number"
  10.         android:textSize="24sp"
  11.         android:layout_centerInParent="true" />
  12. </RelativeLayout>

strings.xml

  1. <resources>
  2.     <string name="app_name">Service</string>
  3. </resources>

【实验结果】

 

【实验分析或心得】

知识点总结

1. Android Manifest 文件配置

-`<manifest>` 标签:定义了应用的包名和权限,以及应用组件(如Activity、Service)的声明。

-`<application>` 标签:包含了应用的所有组件,如Activity和Service。

-`<activity>` 标签:声明了一个Activity,`android:exported`属性指定了Activity是否可以被其他应用启动。

-`<service>` 标签:声明了一个Service,用于后台处理任务。

2. Service 组件

-生命周期方法:

  - `onCreate()`:服务创建时调用。

  - `onStartCommand(Intent intent, int flags, int startId)`:服务开始时调用,用于处理启动命令。

  - `onBind(Intent intent)`:服务绑定时调用,返回一个Binder对象。

  - `onDestroy()`:服务销毁时调用。

-`START_STICKY`:服务启动模式,即使服务被系统销毁,也会被重新创建。

3. Binder 通信机制

- Binder对象:用于Activity和Service之间的通信。

- 内部类RandomNumberBinder:提供了一个方法`getService()`,返回Service的实例。

4. Handler 定时任务

- Handler:用于定时任务和消息处理。

- 定时生成随机数:使用Handler的`postDelayed()`方法,每两秒调用一次。

5. Activity 与 Service 绑定

- ServiceConnection:用于Activity和服务之间的绑定和解绑。

- 绑定和解绑服务:通过`bindService()`和`unbindService()`方法实现。

6. UI 更新

- Handler和Runnable:在Activity中使用Handler和Runnable对象,定时更新UI。

心得体会

1. 理解Service的生命周期:Service是Android中非常重要的组件,用于执行后台任务。理解其生命周期对于正确管理服务至关重要。

2. 掌握Binder通信机制:Binder是Android中进程间通信(IPC)的机制。通过自定义Binder类,可以实现Activity和服务之间的数据通信。

3. 定时任务的重要性:Handler是处理定时任务和消息循环的强大工具。通过Handler,我们可以在后台线程中执行任务,而不会阻塞主线程。

4. UI更新的异步处理:在更新UI时,需要确保操作在主线程中执行。使用Handler可以帮助我们实现这一点,避免在子线程中直接更新UI。

5. 服务的绑定与解绑:绑定服务允许Activity直接与服务交互,获取服务提供的数据。正确管理服务的绑定和解绑,可以避免内存泄漏和其他资源问题。

6. 代码的健壮性:在服务和Activity中,我们需要考虑到各种生命周期事件,确保在适当的时机启动和停止定时任务,以及绑定和解绑服务。

通过这个项目,我更深入地理解了Android的Service组件、Binder通信机制、Handler定时任务以及Activity和服务之间的交互。这些知识点对于开发复杂的Android应用非常重要。

http://www.xdnf.cn/news/16379.html

相关文章:

  • 强化学习(第三课第三周)
  • 在 Scintilla 中为 Squirrel 语言设置语法解析器的方法
  • Kubernetes 配置管理
  • odoo代码分析(一)
  • 认识泛型、泛型类和泛型接口
  • 大语言模型 LLM 通过 Excel 知识库 增强日志分析,根因分析能力的技术方案(2):LangChain + LlamaIndex 实现
  • Java学习第七十七部分——JVM运行时数据区
  • Java同步锁性能优化:15个高效实践与深度解析
  • 7月26号打卡
  • C++/CLI与标准C++的语法差异(一)
  • ASP.NET Core MVC中taghelper的ModelExpression详解
  • Spring Boot 3 如何整合 MinIO 实现分布式文件存储?
  • MyBatis-Plus 通用 Service 详解:IService 与 CRUD 操作全解析
  • PYTHON从入门到实践-15数据可视化
  • 【资讯】2025年软件行业发展趋势:AI驱动变革,云原生与安全成核心
  • PHP框架之Laravel框架教程:1. laravel搭建
  • 亚马逊测评采购:如何打造安全的环境,技术基础关键
  • 2025年渗透测试面试题总结-2025年HW(护网面试) 70(题目+回答)
  • Avantage6.6下载与安装教程
  • 差模干扰 共模干扰
  • 【隧道篇 / IPsec】(7.6) ❀ 01. 利用向导快速建立IPsec安全隧道 (点对点) ❀ FortiGate 防火墙
  • 详解力扣高频SQL50题之550. 游戏玩法分析 IV【中等】
  • ClickHouse高性能实时分析数据库-消费实时数据流(消费kafka)
  • MySQL进阶学习与初阶复习第三天
  • CSS3知识补充
  • 如何高效合并音视频文件(时间短消耗资源少)(二)
  • ICMPv4报文类型详解表
  • 人形机器人指南(八)操作
  • Xinference vs SGLang:详细对比分析
  • MybatisPlus-18.插件功能-分页插件基本用法