后台默默的劳动者,探究服务

深度强化Q学习-基于微软AirSim仿真环境的自动驾驶案例(原理代码详解简易可行) 最近在学习《强化学习原理与Python实现》,肖智清著。参考第十二章的自动驾驶案例,写一篇总结,尽量做到简单可行,让有志于自动驾驶的小伙伴可以通过此篇博客可以管中窥豹,初步了解自动驾驶的强化学习训练过程。 本篇将自动驾驶问题转化为回合制的强化学习任务,设计以车辆观察图像和运行状态为输入的自动驾驶算法,并在AirSim仿真环境中进行训练和测试。本篇使用带经验回放和目标网络的基于深度Q网络算法设计并实现智能体,对经验回放、目标网络和深度Q学习算法进行简单介绍,并用代码实现。 阅读详情

服务是什么

  • 服务(Service)是Android中实现程序后台运行的解决方案,它非常适合去执行那些不需要和用户交互而且还要求长期运行的任务。
  • 服务依赖于创建服务时所在的应用程序进程。

Android多线程

线程的基本用法

  • 继承Thread
class MyThread extends Thread{

    @Override
    public void run(){
        //处理具体逻辑
    }
}
  • 实现Runable接口
class MyThread implements Runnable{

    @Override
    public void run(){
        //实现具体逻辑
    }
}
  • 匿名内部类形式
new Thread(new Runnable(){

    @Override
    public void run(){
        //实现具体逻辑
    }
}).start();

在子线程中更新UI

  • Android的UI是线程不安全的,如果想要更新应用程序里的UI元素,则必须在主线程中进行,否则就会出现异常。
  • 可使用Android中的异步处理机制
public class MainActivity extends Activity implements OnClickListener {
    public static final int UPDATE_TEXT = 1;
    private TextView text;
    private Button changeText;
    private Handler handler = new Handler)(){
        public void handleMessage(Message msg){
            switch (msg.what){
            case UPDATE_TEXT:
                //进行UI操作
                text.setText("Nice to meet you");
                break;
            default:
                break;
            }
        }
    };
    ......
    @Override
    public void onClick(View v){
        switch (v.getId()){
        case R.id.change_text:
            new Thread(new Runnable(){
                @Override
                public void run(){
                    Message message = new Message();
                    message.what = UPDATE_TEXT;
                    handler.sendMessage(message);
                }
            )}.start();
            break;
        default:
            break;
        }
    }
}

当调用Handler的sendMessage()方法将这条Message发送出去,Handler就会收到这条Message,并在handleMessage中进行处理

解析异步消息处理机制

  • Android中的异步消息处理机制主要由四个部分组成,Message、Handler、MessageQueue和Looper。
    • Message是在线程之间传递的消息,它可以在内部携带少量的信息用于不同线程间交换数据
    • Handler 顾名思义也就是处理者的意思,它主要是用于发送和处理消息的。
    • MessageQueue 是消息队列的意思,它主要用于存放所有通过 Handler 发送的消息。
    • Looper 是每个线程中的 MessageQueue 的管家,调用 Looper 的 loop()方法后,就会进入到一个无限循环当中,然后每当发现 MessageQueue 中存在一条消息,就会将它取出, 并传递到 Handler 的 handleMessage()方法中。 每个线程中也只会有一个 Looper 对象。
      这里写图片描述

使用AsyncTask

  • AsyncTask将异步消息处理机制进行了封装
  • AsyncTask是一个抽象类,需要用子类继承它,在继承时可以为AnyncTask指定三个泛型参数
    • Params:在执行AsyncTask时需要传入的参数,可以于在后台任务中使用
    • Progress:后台任务执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为进度单位。
    • Result:当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值类型。
class DownloadTask extends AsyncTask<Void,Integer,Boolean>{
    ......
}
  • 还需重写AsyncTask中的方法
    * onPreExecute():这个方法会在后台任务开始执行之前调用,用于进行一些界面上的初始化操作
    * doInBackground(Params…):这个方法中的所有代码都会在子线程中运行,我们应该在这里去处理所有的耗时任务。任务一旦完成就可以通过 return 语句来将任务的执行结果返回,在此方法中不能进行UI操作
    * onProgressUpdate(Progress…):当在后台任务中调用了 publishProgress(Progress…)方法后,这个方法就会很快被调用,方法中携带的参数就是在后台任务中传递过来的。在这个方法中可以对 UI 进行操作,利用参数中的数值就可以对界面元素进行相应地更新。
    * onPostExecute(Result):当后台任务执行完毕并通过 return 语句进行返回时,这个方法就很快会被调用。返回的数据会作为参数传递到此方法中,可以利用返回的数据来进行一些 UI 操作
class DownloadTask extends AsyncTask<Void,Integer,Boolean>{
    @Override
    protected void onPreExecute(){
        progressDialog.show();
    }

    @Override
    protected Boolean doInBackground(Void...params){
        try{
            while(true){
                int downloadPercent = doDownload();
                publishProgress(downloadPercent);
                if(downloadPercent >= 100){
                    break;
                }
            }
        }catch(Exception e){
            return false:
        }
        return true;
    }

    @Override
    protected void onProgressUpdate(Integer... valuse){
        //更新下载进度
        progressDialog.setMessage("Downloaded " + values[0] + "%");
    }

    @Override
    protected void onPostExecute(Boolean result){
        //关闭进度对话框
        progressDialog.dismiss();
        //提示下载结果
        if(result){
            Toast.makeText(context, "Download succeeded",
Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(context, " Download failed",
Toast.LENGTH_SHORT).show();
        }
    }
}

服务的基本用法

定义一个服务

  • 继承Service类
class MyService extends Service{
    @Override
    public IBinder (Intent intent){
        return null;
    }
}
  • 重写Service中最常用的三个方法
    • onCreate():在服务创建时调用
    • onStartCommand():在服务启动时调用
    • onDestroy():在服务销毁时调用
  • 在AndroidManifest.xml文件中注册服务
<service android:name=".MyService" >
</service>

启动和停止服务

  • 启动服务
Intent startIntent = new Intent(this,MyService.class);
startService(startIntent);
  • 停止服务
Intent stopIntent = new Intent(this,MyService.class);
stopService(stopIntent);
  • onCreate()和onStartCommand()的区别: onCreate()方法是在服务第一次创建的时候调用的,而 onStartCommand()方法则在每次启动服务的时候都会调用。

活动和服务进行通信

  • 思路:专门创建一个Binder对象对下载功能进行管理
public class MyService extends Service{
    private DownloadBinder mBinder = new DownloadBinder();
    class DownloadBinder extends Binder{
        public void startDownload(){
            Log.d("MyService","startDownload executed");
        }

        public int getProgress() {
            Log.d("MyService", "getProgress executed");
            return 0;
        }
    }

    @Override
    public IBinder onBind(Intent intent){
        return mBinder;
    }

    ......
}
public class MainActivity extends Activity implements OnClickListener{
    private Button startService;
    private Button stopService;
    private Button bindService;
    private Button unbindService;
    private MyService.DownloadBinder downloadBinder;
    private ServiceConnection connection = new ServiceConnection(){
        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            downloadBinder = (MyService.DownloadBinder) service;
            downloadBinder.startDownload();
            downloadBinder.getProgress();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ……
        bindService = (Button) findViewById(R.id.bind_service);
        unbindService = (Button) findViewById(R.id.unbind_service);
        bindService.setOnClickListener(this);
        unbindService.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        ……
        case R.id.bind_service:
            Intent bindIntent = new Intent(this, MyService.class);
            // 绑定服务
            bindService(bindIntent, connection, BIND_AUTO_CREATE); 
            break;
        case R.id.unbind_service:
            // 解绑服务
            unbindService(connection); 
            break;
        default:
            break;
        }
    }
}

服务的生命周期

服务的更多技巧

使用前台服务

public class MyService extends Service{
    ......
    @Override
    public void onCreate(){
        super.onCreate();
        Notification notification = new Notification(R.drawable.ic_launcher,"Notification comes",System.currentTimeMillis());
        Intent notificationIntent = new Intent(this,MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
        notification.setLatestEventInfo(this, "This is title", "This is content", pendingIntent);
        startForeground(1, notification);
        Log.d("MyService", "onCreate executed");
    }
    ......
}

使用IntentService

public class MyIntentService extends IntentService {
    public MyIntentService() {
        super("MyIntentService"); // 调用父类的有参构造函数
    }
    @Override
    protected void onHandleIntent(Intent intent) {
        // 打印当前线程的id
        Log.d("MyIntentService", "Thread id is " + Thread.currentThread().getId());
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("MyIntentService", "onDestroy executed");
    }
}
  • 在onHandleIntent中可以处理一些具体的逻辑,而且不用担心ANR的问题,因为这个方法已经是在子线程是运行
流体动力学仿真软件:Star-CCM+_(1).Star-CCM+基础及入门 Star-CCM+的用户界面(UI)分为多个部分,包括菜单栏、工具栏、工作区、视图窗口和控制台。菜单栏包含文件、编辑、视图、工具等常用菜单。例如,“File”菜单可以用于打开、保存和退出项目。工具栏提供常用的工具按钮,如新建项目、打开项目、保存项目等。也可以自定义工具栏,添加常用的功能按钮。工作区显示当前项目的结构和各个对象。可以通过拖拽方式组织和管理项目中的各个部分。视图窗口显示几何模型、网格、结果等。可以通过不同的视图模式查看和分析数据。控制台显示软件的运行日志和输出信息。 阅读详情

相关推荐

XPe开发初体验(一)XPe概述

XP Embedded是微软Windows Embedded产品线中非常重要的一环,不过比起大名鼎鼎的Windows Embedded CE,XPe显得过于低调了。在接下来的一段时间里,我希望能够用六篇的篇幅来描述一下XPe的整个开发过程。这个系列文章主要是针对有Windows编程经验,但是没有嵌入式开发经验的开发者,提供一些概念和开发过程的初步介绍。XP Embedded是一个基于Windo

aawolf = new Mobile.MVP 1万+

8月8日 第9章 后台默默的劳动者,探究Service

首先看一下如何在项目中定义一个Service。新建一个ServiceTest项目,然后右击 com.example.servicetest→New→Service→Service这里我们将类名定义成MyService,Exported属性表示是否将这个Service暴露给外部其他程序访问,Enabled属性表示是否启用这个Service。将两个属性都勾中,点击“Finish”完成创建MyService 中的代码;@Override可以看到,MyService是继承自系统的Service类的。

lin_li17的博客 1061

用blender为模型贴图并在gazebo中显示

用blender为模型贴图并在gazebo中显示 首先我用的是最新的blender2.92版本,附上链接https://www.blender.org/download/。并设置好简体中文。语言可以在编辑->偏好设置->界面里面设置。 首先界面右上角的摄像头,方块,灯光三个场景全都删除。 接着导入stl格式的模型文件,下面以tianbot_mini上面的激光雷达的模型为例。 导入激光雷达模型后,点击进入上方的UV Editing按钮进入UV编辑界面 此时我面看见网格化的激光雷达模型

qq_48427527的博客 8000

Android Studio学习笔记——后台默默的劳动者——探究服务Service

在项目的任何位置调用startService()方法,相应的服务就会启动起来,并回调onStartCommand()方法。如果这个方法没有被执行过,那么先执行OnCreate()再执行onStartCommand()。服务启动之后会一直保持运行状态,直到stopService()或者stopSelf()方法执行。每个服务只会存在一个实例,不管调用多少次startService()方法,所以只需调用一次stopService()或者stopSelf()服务就会停止。

我的的博客 1494

基于STM32的Keil5代码自动补全设置操作指南

掌握Keil5代码自动补全设置技巧,提升STM32开发效率。通过合理配置编辑器选项,实现智能提示与语法补全,让嵌入式编程更流畅,尤其适合使用keil5代码自动补全设置的开发者快速上手。

weixin_32287387的博客 762

运动控制软件:Siemens Sinamics二次开发_(6).通信接口与协议详解

PROFIBUSPROFINETModbus TCPCANopenEtherCAT每种通信接口都有其特定的应用场景和优势。选择合适的通信接口可以显著提高系统的性能和可靠性。在选择通信协议时,需要根据具体的应用场景和需求综合考虑。每种通信协议都有其特定的优势和局限性,因此在设计运动控制系统时,应选择最适合的协议,以确保系统的性能、可靠性、成本和维护性。通过以上对比和分析,希望开发者能够更好地理解和选择适合的通信接口和协议,从而优化运动控制系统的开发和应用。

2401_87715305的博客 898

后台默默的劳动者,探究Service

Service是什么 Service是Android中实现程序后台运行的解决方案,它非常适合执行那些不需要和用户交互而且还要求长期运行的任务。Service的运行不依赖于任何用户界面,即使程序被切换到后台,或者用户打开另一个应用程序,Service仍然能够保持正常运行。 不过需要注意的是,Service并不是运行在一个独立的进程当中的,而是依赖于创建Service时所在的应用程序进程。当某个应用程序被杀掉时,所有依赖于该进程的Service也会停止运行。 另外,也不要被Service的后台概念所迷惑,实际上

qq_36828822的博客 261

资产会计 Transaction Type 与业务交易的 Post to Affiliated Company 不一致导致的 AAPO176:成因剖析与修复指引

本文解析了SAP资产会计中常见的"AAPO176"错误提示,指出当交易类型(TType)与业务交易(Business Transaction)的"关联公司过账"(Post to Affiliated Company)标志不一致时,系统会拒绝过账。作者详细说明了该标志的作用机制,并提供了四种解决方案:修正交易类型使用、匹配正确的业务交易、调整系统配置或建立映射关系。文章还通过实际案例展示了配置错误对集团合并报表的影响,并附带了用于检查配置一致性的ABAP脚本。该错误通常

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 394

第10章 后台默默的劳动者——探究服务

首先看一下如何在项目中定义一个服务。新建一个ServiceTest项目,然后右击com.zhouzhou. servicetest→New→Service→Service→MyService,会弹出如图所示的窗口:将服务命名为MyService, Exported属性表示是否允许除了当前程序之外的其他程序访问这个服务,Enabled属性表示是否启用这个服务。将两个属性都勾中,点击Finish完成创建。@OverrideMyService是继承自Service类的,说明这是一个服务。

Roderick888888的博客 721

基于SpringBoot 3 + Vue 3的全栈民宿预约管理系统设计与实现

文章将详细阐述系统的需求分析、架构设计、数据库设计、核心功能模块的实现(包括用户认证、房源管理、订单流程、支付集成等),并提供关键代码片段,最后对系统进行总结与展望。.requestMatchers("/api/admin/**").hasRole("ADMIN") // 管理员接口。.requestMatchers("/api/auth/**").permitAll() // 认证接口公开。.requestMatchers("/api/public/**").permitAll() // 公开资源。

2201_76125393的博客 272

微观交通流仿真软件:SUMO (Simulation of Urban MObility)_(8).仿真场景创建与编辑

总结文件()包含了仿真过程中的总体统计信息,如车辆生成数、平均速度等。加载总结文件使用Python的提取关键信息通过以上步骤,可以使用SUMO及其相关工具和库创建和编辑交通仿真场景。无论是手动创建、使用工具转换现有数据,还是通过Python脚本自动生成,SUMO都提供了丰富的功能来满足不同需求。此外,Traci库允许在仿真过程中动态调整交通场景,从而实现更精细的控制和优化。最后,通过对输出文件的分析,可以评估仿真结果并进行进一步的改进。

kkchenjj的博客 1268

第十章 后台默默的劳动者-探究服务

10.1 服务是什么 服务(service)是实现程序后台运行的解决方案,适合执行那些不需要和用户交互而且还要求长期运行的任务 注意1:它依赖于创建服务时所在的应用程序进程. 应用程序被杀死,服务结束。 注意2:它不会在应用程序切换时,关闭掉 10.2 Android 多线程编程 10.2.1 线程的基本用法 方法一: cla...

julicliy的博客 248

影楼精修-肤色统一算法解析

本文介绍了影楼精修中肤色统一算法的实现方案,并以像素蛋糕软件为例进行详细分析。肤色统一旨在通过调整人像照片中皮肤区域的颜色,使其看起来更加均匀一致。像素蛋糕软件提供了AI肤色统一和传统肤色统一两种功能,分别适用于不同需求。传统肤色统一算法通过皮肤分割、人脸检测、亮度统一和颜色统一等步骤,实现了对皮肤区域的精细调整。文章还提供了亮度统一的核心代码,并对比了传统算法与AI算法的效果,指出AI算法在自然度和亮度矫正方面表现更优。整体而言,本文为影楼精修中的肤色统一提供了实用的技术参考。

Trent1985的专栏 2065

第九章 后台默默的劳动者,探究服务

9.1服务是什么服务( Service)是 Android 中实现程序后台运行的解决方案,它适合用于去执行不需要和用户交互而且还要求长期运行的任务。服务的运行不依赖于任何用户界面,当程序被切换到后台,服务仍然能够保持正常运行。但服务并不是运行在一个独立的进程当中的,而是依赖于创建服务时所在的应用程序进程。当某个应用程序进程被杀掉时,所有依赖于该进程的服务也会停止运行。另外,服务并不会自动开启线程,所

wjoker的博客 705

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

第十章:后台默默的劳动者-探究服务

不能在自定义线程中更新 UI,系统本身不允许 如果想在自定义线程中更新 UI,需要使用 Handler 机制。上一章中的 runOnUiThread 方法也是对 Handler 机制的一种包装 AsyncTask 背后的原理也是基于异步消息处理机制的 活动绑定服务,通过活动中的 ServiceConnection 链接到服务中的 Binder 实例 源码 源码见:https://github....

weixin_30847865的博客 133

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

第二行代码学习笔记——第十章:后台默默的劳动者——探究服务

本章要点Android沿用了诺基亚系统的Symbian操作系统的老习惯,从一开始就支持后台功能,这使得应用程序即使在关闭的情况下仍然可以在后台继续运行。后台功能属于四大组件之一,重要程度言不可寓。10.1 服务是什么服务(Service)是Android中是实现程序后台运行的解决方案,它非常适合执行那些不需要与用户进行交互还需要长期运行的任务。服务的界面不依赖于任何用户界面,即使程序被切换到后台,或

JiangWeiHu的博客 1477

阅读郭霖《第一行代码》的笔记——第9章 后台默默的劳动者,探究服务

一、服务是什么,Android多线程编程1、服务是什么服务(Service)是Android中实现程序后台运行的解决方案,它非常适合用于去执行那些不需要和用户交互而且还要求长期运行的任务。服务的运行不依赖于任何用户界面,即使当程序被切换到后台,或者用户打开了另外一个应用程序,服务仍然能够保持正常运行。不过需要注意的是,服务并不是运行在一个独立的进程当中的,而是依赖于创建服务时所在的应用程序进程。当某

持续学习,刻意练习 1926

第一行代码 学习笔记 后台的默默劳动者--探究服务

10.1 服务是什么10.2 Android多线程编程定义线程:新建一个类继承自Thread,然后重写父类的run()方法,如下所示:class MyThread extends Thread{      public void run(){        //处理具体的逻辑      }}启动线程:如下所示new MyThread().start();当然,使用继承的方式耦合性有点高,更多的时候...

qq_37635604的博客 425

第一行代码——第十章:后台默默的劳动者——探究服务

目录: 10.1 服务是什么 10.2 Android 多线程编程 10.2.1 线程的基本用法 10.2.2 在子线程中更新UI 10.2.3 解析异步消息处理机制 10.2.4 使用AsyncTask 10.3 服务的基本用法 10.3.1 定义一个服务 10.3.2 启动和停止服务 10.3.3 活动和服务进行通信 10.4 服务的声明周期 10.5 服务的更多技巧 ...

李某人_ 6009

Android 学习笔记 - 《第一行代码 Android 第二版》 第10章 后台默默的劳动者——探究服务

本章主要学习了 服务的用法(前台服务、后台服务) Android中多线程的应用 (AsyncTask 类) 最后通过一个综合例子实现下载功能。基本搞懂这个例子本章就学完了。 先介绍下几个主要的类 /** * 主活动(UI线程)工作如下: * 1、初始化 UI 界面,绑定按钮事件。 * 2、实例化 ServiceConnection 通过他的 onServiceConnected 回调函数...

灵台方寸山斜月三星洞 730

十、后台默默的劳动者,探究Service

《第一行代码-Android》第十章读书笔记

qq_44663000的博客 555

后台劳动者--探究服务

目标 1、基本用法 2、启动和停止服务 3、活动和服务进行通信 4、服务的生命周期 5、前台服务(类似网易云音乐通知栏常驻) 6、使用IntentService(服务在主线程运行比较容易出现ANR,所以需使用Android的多线程) 1、2两个按钮用于启动和停止服务,3、4两个按钮在之前的基础上加强了活动和服务之间的关系,在活动中指挥服务。(需要创建一个专门的Binder对象来对相

月满轩尼诗 369

第10章 后台默默的劳动者,探究Service

在 Android 开发中,Service 是实现后台任务的核心组件。它能在不依赖用户界面的情况下长期运行,非常适合执行下载、音乐播放、数据同步等不需要用户交互的任务。

欢迎大家一起讨论交流 847

android service探究(附:使用服务功能下载文件)

本节来说说service的那些事。

Wedfrend的博客 869

关于《第一行代码Android》对于后台阐释的补充

《第一行代码Android》第一版第9章大标题内容是“后台默默的劳动者,探究服务”,章节引言部分首先介绍了后台的相关知识,提到“在这三大智能手机操作系统中,IOS是不支持后台的,当应用程序不在前台运行时就会进入到挂起状态。Android则是沿用了Symbian的老习惯,加入了后台功能,这使得应用程序即使在关闭的情况下仍然可以在后台继续运行。而Windows Phone则是经历了一个由不支持到支

whatever9527的博客 449

第九章 服务

服务 这使得应用程序即使在关闭的情况下仍然可以在后台继续运行 服务并不是运行在一个独立的进程当中的,而是依赖于创建服务 时所在的应用程序进程。当某个应用程序进程被杀掉时,所有依赖于该进程的服务也会停 止运行。 实际上服务并不会自动开启线程,所有的代码 都是默认运行在主线程当中的 new Thread(new Runnable() { @Override

jonemill的专栏 530
上一篇: 丰富你的程序,运用手机多媒体
下一篇: Fragment学习之旅(一)
guotao967
博客等级 码龄11年 1粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值