Android语言基础教程(236)Android创建Started Service实例之继承Service输出当前时间:Android后台打工仔:教你用Service做个低调的时间管家,老板再也不用

嘿,各位搞机的小伙伴们!今天咱们来聊一个Android开发中超级实用的技能——创建Started Service。说白了,这就是给你的应用请个“后台打工仔”,让它能在你没盯着屏幕的时候默默干活。比如定时提醒、播放音乐,或者像我们今天要做的,持续输出当前时间。

一、Service是个啥?先别被名字吓到!

很多安卓新手一听到“Service”就头大,觉得这玩意儿肯定很复杂。其实不然!你可以把Service想象成你家请的保姆:Activity(界面)是你在家时面对面交流,而Service是你出门后保姆还在家里打扫卫生。它没有界面,但能在后台默默工作。

Started Service特别像你给保姆下个指令:“我去上班了,你把地拖一下。”之后保姆就自己干活,不需要你再实时指挥。这就是Started Service的特点——启动后独立运行,即使你关闭了应用界面,它还能继续工作(当然,得看系统心情,内存不够时可能会被清理)。

二、为什么需要自己继承Service?

Android虽然提供了一些现成的服务,但真实开发中,我们经常需要定制自己的服务。比如:

  • 定时从服务器拉取数据
  • 长时间计算任务
  • 监控某些系统状态
  • 或者像我们的例子——持续输出时间

继承Service类就像是给这个“打工仔”定制工作内容,你想让它干啥就干啥,自由度超高!

三、手把手实战:打造你的时间管家

接下来,咱们直接上硬货,一步步创建一个输出当前时间的Started Service。

第一步:创建TimeService类

public class TimeService extends Service {
    private static final String TAG = "TimeService";
    private boolean isRunning = false;
    private Thread backgroundThread;
    
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "服务创建了,准备开始打工!");
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        // Started Service不需要绑定,所以返回null
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "老板发指令了,开始输出时间!");
        
        if (!isRunning) {
            isRunning = true;
            startTimeOutput();
        }
        
        // 如果服务被杀了,系统会尝试重新创建
        return START_STICKY;
    }

    private void startTimeOutput() {
        backgroundThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (isRunning) {
                    try {
                        // 每秒输出一次当前时间
                        String currentTime = new SimpleDateFormat("HH:mm:ss", Locale.getDefault())
                                .format(new Date());
                        Log.d(TAG, "当前时间:" + currentTime);
                        
                        // 如果想在通知栏显示,可以在这里添加通知代码
                        createNotification(currentTime);
                        
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        Log.e(TAG, "打工线程被中断了", e);
                    }
                }
            }
        });
        backgroundThread.start();
    }

    private void createNotification(String time) {
        // 创建通知让用户知道服务在运行
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "time_channel")
                .setContentTitle("时间管家工作中")
                .setContentText("当前时间:" + time)
                .setSmallIcon(R.drawable.ic_time_icon);
        
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        manager.notify(1, builder.build());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "服务被销毁了,下班!");
        isRunning = false;
        if (backgroundThread != null) {
            backgroundThread.interrupt();
        }
    }
}

第二步:在AndroidManifest.xml里声明服务

光写代码不行,还得在“户口本”上登记:

<application>
    <!-- 其他组件 -->
    <service android:name=".TimeService" />
</application>

第三步:在Activity里启动和停止服务

public class MainActivity extends AppCompatActivity {
    private Intent serviceIntent;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        serviceIntent = new Intent(this, TimeService.class);
        
        Button startBtn = findViewById(R.id.start_btn);
        Button stopBtn = findViewById(R.id.stop_btn);
        
        startBtn.setOnClickListener(v -> {
            startService(serviceIntent);
            Toast.makeText(this, "启动时间服务", Toast.LENGTH_SHORT).show();
        });
        
        stopBtn.setOnClickListener(v -> {
            stopService(serviceIntent);
            Toast.makeText(this, "停止时间服务", Toast.LENGTH_SHORT).show();
        });
    }
}
四、避坑指南:这些坑我都替你踩过了
  1. 别忘了线程! Service默认运行在主线程,长时间任务一定要开子线程,否则会ANR(应用无响应)。上面的例子我们用Thread来处理,实际项目中可以考虑HandlerThread或协程。
  2. 通知渠道要创建 (Android 8.0+):现代Android版本要求通知必须有渠道。在Activity里添加:
private void createNotificationChannel() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(
                "time_channel",
                "时间通知",
                NotificationManager.IMPORTANCE_LOW
        );
        NotificationManager manager = getSystemService(NotificationManager.class);
        manager.createNotificationChannel(channel);
    }
}
  1. 服务保活是个玄学:别指望Started Service能永远运行,系统内存不足时照样会被杀。重要的任务建议用JobScheduler或WorkManager。
  2. 耗电问题要注意:频繁唤醒设备会很耗电,用户可能会手动杀死你的服务。要节制使用!
五、运行效果:看看你的“打工仔”干得怎么样

当你点击启动按钮后,打开Logcat过滤“TimeService”,就会看到每秒输出一次时间:

D/TimeService: 服务创建了,准备开始打工!
D/TimeService: 老板发指令了,开始输出时间!
D/TimeService: 当前时间:14:30:01
D/TimeService: 当前时间:14:30:02
D/TimeService: 当前时间:14:30:03
...

同时状态栏会有持续的通知显示当前时间。即使你退出应用,服务还会继续运行,直到你点击停止按钮或系统回收资源。

六、进阶玩法:让你的服务更智能

掌握了基础版后,你可以尝试:

  • 添加定时任务,只在特定时间输出
  • 将时间数据通过广播发送给其他组件
  • 与前台服务结合,提升存活几率
  • 添加配置选项,让用户自定义输出间隔
七、总结

看到这里,你已经成功get了Android Started Service的核心技能!记住几个关键点:

  • 继承Service类,重写onStartCommand()
  • 耗时操作一定要在子线程进行
  • 启动用startService(),停止用stopService()
  • 做好通知和资源管理

Service就像是你应用里的幕后英雄,虽然用户看不见,但却在默默提供价值。现在就去试试这个时间管家吧,相信你会对Android后台机制有更深的理解!

(完)


字数统计:本篇正文约1800字,包含完整可运行代码示例和实用技巧,适合Android初学者和需要复习Service的开发者。跟着做一遍,包你学会!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

值引力

持续创作,多谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值