A default binder has been requested

android 16 蓝牙源码分析 本文分析了Android 16系统中蓝牙开启的完整调用链路,从应用层到硬件驱动的详细流程。当应用调用BluetoothAdapter.enable()后,请求依次经过Framework层、Service层、JNI层、HAL层,最终到达蓝牙协议栈和HCI层。关键步骤包括:BluetoothManagerService处理状态转换,AdapterService初始化蓝牙协议栈,通过JNI调用底层接口,HciHalImpl与硬件交互完成上电。整个过程涉及多线程协作、异步回调、状态机管理等机制,最终通过stack_ 阅读详情

A default binder has been requested

在将Spring Cloud Stream升级到3.1.3之后。某些项目启动会报***A default binder has been requested, but there is more than one binder available for ‘org.springframework.cloud.stream.messaging.DirectWithAttributesChannel’ : rocketmq,mqtt,kafka,rabbit,
amqpjms, and no default binder has been set.***错误

原因

从报错信息可知,项目启动时创建了一个通道,但并没有指定绑定器。因此会去使用默认配置的绑定起器,但默认绑定器没有配置,并且发现了rocketmq,mqtt,kafka,rabbit,amqpjms这几种类型的绑定器。当然这个通道可能并不是你项目里面显示创建的,也许是你依赖的某个组件其内部自动创建的

解决思路

自己创建的通道

对于自己创建的通道,如果报上面的错误,或类似的没有默认绑定器的错误,请设置默认绑定器或者指定自己创建通道的绑定器

依赖组件创建的通道

这个情况比较复杂,根据自己需求确定需要采取何种处理方式

  • 对于这个通道如果无需使用,也不想设置默认绑定器,则需要根据依赖组件的具体使用方式,想办法不让其创建通道,下面会有具体案例。例如通道是通过实现Supplier、Function、Consumer,并通过函数式通道自动发现的,可以通过spring.cloud.stream.function.autodetect=false,关闭自动发现

  • 如果需要这个通道,则可以设置默认绑定器

原因分析

根据报错日志可定位到报错代码位置为DefaultBinderFactory类的doGetBinder方法,该方法获取绑定器。查看报错位置代码可知,candidatesForBindableType候选绑定器不为1,则会报出此错误,而candidatesForBindableType则是通过binderConfigurations解析出来的,binderConfigurations是Spring Cloud Stream启动时扫描绑定器的配置文件来的,每种类型的绑定器都会有

private <T> Binder<T, ConsumerProperties, ProducerProperties> doGetBinder(String name, Class<? extends T> bindingTargetType) {
    String configurationName;
    Binder binderInstance;
    if (!MessageChannel.class.isAssignableFrom(bindingTargetType) && !PollableMessageSource.class.isAssignableFrom(bindingTargetType)) {
        configurationName = StringUtils.hasText(name) ? name : bindingTargetType.getSimpleName().toLowerCase();
        binderInstance = this.getBinderInstance(configurationName);
        return binderInstance;
    } else {
        if (StringUtils.isEmpty(name)) {
            Assert.notEmpty(this.binderConfigurations, "A default binder has been requested, but there is no binder available");
            if (!StringUtils.hasText(this.defaultBinder)) {
                Set<String> defaultCandidateConfigurations = new HashSet();
                Iterator var5 = this.binderConfigurations.entrySet().iterator();

                while(var5.hasNext()) {
                    Entry<String, BinderConfiguration> binderConfigurationEntry = (Entry)var5.next();
                    if (((BinderConfiguration)binderConfigurationEntry.getValue()).isDefaultCandidate()) {
                        defaultCandidateConfigurations.add(binderConfigurationEntry.getKey());
                    }
                }

                if (defaultCandidateConfigurations.size() == 1) {
                    configurationName = (String)defaultCandidateConfigurations.iterator().next();
                    this.defaultBinderForBindingTargetType.put(bindingTargetType.getName(), configurationName);
                } else {
                    List<String> candidatesForBindableType = new ArrayList();
                    Iterator var12 = defaultCandidateConfigurations.iterator();

                    while(var12.hasNext()) {
                        String defaultCandidateConfiguration = (String)var12.next();
                        Binder<Object, ?, ?> binderInstance = this.getBinderInstance(defaultCandidateConfiguration);
                        Class<?> binderType = GenericsUtils.getParameterType(binderInstance.getClass(), Binder.class, 0);
                        if (binderType.isAssignableFrom(bindingTargetType)) {
                            candidatesForBindableType.add(defaultCandidateConfiguration);
                        }
                    }

                    if (candidatesForBindableType.size() != 1) {
                        // 报错位置
                        String countMsg = candidatesForBindableType.size() == 0 ? "are no binders" : "is more than one binder";
                        throw new IllegalStateException("A default binder has been requested, but there " + countMsg + " available for '" + bindingTargetType.getName() + "' : " + StringUtils.collectionToCommaDelimitedString(candidatesForBindableType) + ", and no default binder has been set.");
                    }

                    configurationName = (String)candidatesForBindableType.iterator().next();
                    this.defaultBinderForBindingTargetType.put(bindingTargetType.getName(), configurationName);
                }
            } else {
                configurationName = this.defaultBinder;
            }
        } else {
            configurationName = name;
        }

        binderInstance = this.getBinderInstance(configurationName);
        Assert.state(this.verifyBinderTypeMatchesTarget(binderInstance, bindingTargetType), "The binder '" + configurationName + "' cannot bind a " + bindingTargetType.getName());
        return binderInstance;
    }
}

通过方法调用栈可知,doGetBinder方法在DefaultBinderFactory类的getBinder方法中被调用,在getBinder方法中,会首先处理绑定器名称,如果绑定器名称为空,则使用默认绑定器名称,但当前我们运行项目并没有设置绑定器名称,也没有设置默认绑定器名称。因此走到了doGetBinder方法

public synchronized <T> Binder<T, ?, ?> getBinder(String name, Class<? extends T> bindingTargetType) {
    String binderName = StringUtils.hasText(name) ? name : this.defaultBinder;
    Map<String, Binder> binders = this.context == null ? Collections.emptyMap() : this.context.getBeansOfType(Binder.class);
    Binder binder;
    if (StringUtils.hasText(binderName) && binders.containsKey(binderName)) {
        binder = (Binder)this.context.getBean(binderName);
    } else if (binders.size() == 1) {
        binder = (Binder)binders.values().iterator().next();
    } else {
        if (binders.size() > 1) {
            throw new IllegalStateException("Multiple binders are available, however neither default nor per-destination binder name is provided. Available binders are " + binders.keySet());
        }

        binder = this.doGetBinder(binderName, bindingTargetType);
    }

    if (this.binderCustomizer != null) {
        this.binderCustomizer.customize(binder, binderName);
    }

    return binder;
}

在大概清楚了为什么报错之后,我们需要寻找到是那里进行的通道创建,及创建的逻辑。通过分析调用栈我们可以找到AbstractBindableProxyFactory类的createAndBindOutputs方法,在此方法中,我们发现outputHolders属性,此属性中存放了解析生成的错误通道,此方法就是在将绑定器绑定到输出通道。我们需要找到outputHolders属性是在哪里进行的设置

public Collection<Binding<Object>> createAndBindOutputs(
    BindingService bindingService) {
    List<Binding<Object>> bindings = new ArrayList<>();
    if (log.isDebugEnabled()) {
        log.debug(String.format("Binding outputs for %s:%s", this.namespace,
            this.type));
    }
    for (Map.Entry<String, BoundTargetHolder> boundTargetHolderEntry : this.outputHolders
        .entrySet()) {
        BoundTargetHolder boundTargetHolder = boundTargetHolderEntry.getValue();
        String outputTargetName = boundTargetHolderEntry.getKey();
        if (boundTargetHolderEntry.getValue().isBindable()) {
            if (log.isDebugEnabled()) {
                log.debug(String.format("Binding %s:%s:%s", this.namespace, this.type,
                    outputTargetName));
            }
            bindings.add(bindingService.bindProducer(
                boundTargetHolder.getBoundTarget(), outputTargetName));
        }
    }
    return bindings;
}

通过分析代码可知BindableFunctionProxyFactory类的createOutput方法进行了设置

private void createOutput(String name) {
    if (this.functionProperties.getBindings().containsKey(name)) {
        name = this.functionProperties.getBindings().get(name);
    }
    this.outputHolders.put(name,
            new BoundTargetHolder(getBindingTargetFactory(MessageChannel.class)
                    .createOutput(name), true));
}

createOutput方法的调用是在BindableFunctionProxyFactory类的afterPropertiesSet方法中调用的,这个方法是bean初始化后调用,我们观察到在此类中functionDefinition属性值为***inMemorySwaggerResourcesProvider***,此属性是在构造函数中设置

public void afterPropertiesSet() {
    populateBindingTargetFactories(context.getBeanFactory());
    Assert.notEmpty(BindableFunctionProxyFactory.this.bindingTargetFactories,
            "'bindingTargetFactories' cannot be empty");

    if (this.inputCount > 0) {
        for (int i = 0; i < inputCount; i++) {
            this.createInput(this.buildInputNameForIndex(i));
        }
    }

    if (this.outputCount > 0) {
        for (int i = 0; i < outputCount; i++) {
            this.createOutput(this.buildOutputNameForIndex(i));
        }
    }
}

BindableFunctionProxyFactory(String functionDefinition, int inputCount, int outputCount, StreamFunctionProperties functionProperties,
        boolean pollable) {
    super(null);
    this.inputCount = inputCount;
    this.outputCount = outputCount;
    this.functionDefinition = functionDefinition;
    this.functionProperties = functionProperties;
    this.pollable = pollable;
}

下载依赖组件源码,全局搜索functionDefinition属性值,发现InMemorySwaggerResourcesProvider类,此类为依赖Swagger组件中的类,观察此类,发现此类实现了Supplier接口。在最新的3.1.3版本的Spring Cloud Stream支持函数编程,实现消息的发送与消费,详情查看Spring Cloud Stream,由此可知产生的输出通道其实就是InMemorySwaggerResourcesProvider类产生的

@Component
public class InMemorySwaggerResourcesProvider implements SwaggerResourcesProvider, ApplicationContextAware 

public interface SwaggerResourcesProvider extends Supplier<List<SwaggerResource>> 

我们目前知道了产生问题的地方,如果对Spring Cloud Stream很属性也应该知道解决方法是什么。我们这边再继续跟踪源码,进行更深入的分析。我们需要知道哪里调用了BindableFunctionProxyFactory的构造方法设置functionDefinition属性。通过代码分析我们可以发现FunctionBindingRegistrar完成bean初始化后在afterPropertiesSet方法中实现了对BindableFunctionProxyFactory构造函数的调用,调用方式是通过获取其RootBeanDefinition,动态调用的构造方法并注册functionDefinition + "_binding"命名的bean。我们发现通过判断streamFunctionProperties的definition属性是否有值决定是否进入之后的处理方法

public void afterPropertiesSet() throws Exception {
    if (ObjectUtils.isEmpty(applicationContext.getBeanNamesForAnnotation(EnableBinding.class))) {
        this.determineFunctionName(functionCatalog, environment);
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) applicationContext.getBeanFactory();

        if (StringUtils.hasText(streamFunctionProperties.getDefinition())) {
            String[] functionDefinitions = this.filterEligibleFunctionDefinitions();
            for (String functionDefinition : functionDefinitions) {
                RootBeanDefinition functionBindableProxyDefinition = new RootBeanDefinition(BindableFunctionProxyFactory.class);
                FunctionInvocationWrapper function = functionCatalog.lookup(functionDefinition);
                if (function != null) {
                    Type functionType = function.getFunctionType();
                    if (function.isSupplier()) {
                        this.inputCount = 0;
                        this.outputCount = this.getOutputCount(functionType, true);
                    }
                    else if (function.isConsumer() || functionDefinition.equals(RoutingFunction.FUNCTION_NAME)) {
                        this.inputCount = FunctionTypeUtils.getInputCount(functionType);
                        this.outputCount = 0;
                    }
                    else {
                        this.inputCount = FunctionTypeUtils.getInputCount(functionType);
                        this.outputCount = this.getOutputCount(functionType, false);
                    }

                    functionBindableProxyDefinition.getConstructorArgumentValues().addGenericArgumentValue(functionDefinition);
                    functionBindableProxyDefinition.getConstructorArgumentValues().addGenericArgumentValue(this.inputCount);
                    functionBindableProxyDefinition.getConstructorArgumentValues().addGenericArgumentValue(this.outputCount);
                    functionBindableProxyDefinition.getConstructorArgumentValues().addGenericArgumentValue(this.streamFunctionProperties);
                    registry.registerBeanDefinition(functionDefinition + "_binding", functionBindableProxyDefinition);
                }
                else {
                    logger.warn("The function definition '" + streamFunctionProperties.getDefinition() +
                            "' is not valid. The referenced function bean or one of its components does not exist");
                }
            }
        }

        if (StringUtils.hasText(this.environment.getProperty(SOURCE_PROPERY))) {
            String[] sourceNames = this.environment.getProperty(SOURCE_PROPERY).split(";");

            for (String sourceName : sourceNames) {
                if (functionCatalog.lookup(sourceName) == null) {
                    RootBeanDefinition functionBindableProxyDefinition = new RootBeanDefinition(BindableFunctionProxyFactory.class);
                    functionBindableProxyDefinition.getConstructorArgumentValues().addGenericArgumentValue(sourceName);
                    functionBindableProxyDefinition.getConstructorArgumentValues().addGenericArgumentValue(0);
                    functionBindableProxyDefinition.getConstructorArgumentValues().addGenericArgumentValue(1);
                    functionBindableProxyDefinition.getConstructorArgumentValues().addGenericArgumentValue(this.streamFunctionProperties);
                    registry.registerBeanDefinition(sourceName + "_binding", functionBindableProxyDefinition);
                }
            }
        }
    }
    else {
        logger.info("Functional binding is disabled due to the presense of @EnableBinding annotation in your configuration");
    }
}

通过代码分析发现determineFunctionName方法实现了对streamFunctionProperties属性的设置。在此方法中首先获取环境变量中设置的spring.cloud.stream.function.autodetect,如果未设置则默认为true。从streamFunctionProperties获取definition值,如果没有则从环境变量中获取spring.cloud.function.definition值作为definition,并回写到streamFunctionProperties,如果没有则继续查找,最后如果前面都没找到并且autodetect为true,则会通过自动扫描函数接口获取。如果将spring.cloud.stream.function.autodetect设置为false则不会自动扫描

private boolean determineFunctionName(FunctionCatalog catalog, Environment environment) {
    boolean autodetect = environment.getProperty("spring.cloud.stream.function.autodetect", boolean.class, true);
    String definition = streamFunctionProperties.getDefinition();
    if (!StringUtils.hasText(definition)) {
        definition = environment.getProperty("spring.cloud.function.definition");
    }

    if (StringUtils.hasText(definition)) {
        streamFunctionProperties.setDefinition(definition);
    }
    else if (Boolean.parseBoolean(environment.getProperty("spring.cloud.stream.function.routing.enabled", "false"))
            || environment.containsProperty("spring.cloud.function.routing-expression")) {
        streamFunctionProperties.setDefinition(RoutingFunction.FUNCTION_NAME);
    }
    else if (autodetect) {
        streamFunctionProperties.setDefinition(((FunctionInspector) functionCatalog).getName(functionCatalog.lookup("")));
    }
    return StringUtils.hasText(streamFunctionProperties.getDefinition());
}

继续跟踪FunctionCatalog的lookup方法,我们会发现所有实现了Function、Supplier、Consumer的类都会被扫出来

public Set<String> getNames(Class<?> type) {
    Set<String> registeredNames = super.getNames(type);
    if (type == null) {
        registeredNames
            .addAll(Arrays.asList(this.applicationContext.getBeanNamesForType(Function.class)));
        registeredNames
            .addAll(Arrays.asList(this.applicationContext.getBeanNamesForType(Supplier.class)));
        registeredNames
            .addAll(Arrays.asList(this.applicationContext.getBeanNamesForType(Consumer.class)));
    }
    else {
        registeredNames.addAll(Arrays.asList(this.applicationContext.getBeanNamesForType(type)));
    }
    return registeredNames;
}

总结

通过上面源码分析,对于报错的原因有了深入的了解。我们可以根据自己的需求进行设置。比如将spring.cloud.stream.function.autodetect设置为false禁用自动扫描,去除不需要的函数类生成消息通道

JavaWeb之Springboot原理与实战 启动SpringBoot项目的主入口程序 HelloController.java文件内容如下: 在浏览器输入localhost:8888/hello 三、Springboot3+MyBatis+Swagger整合实战 项目结构 数据库表结构 阅读详情

相关推荐

Android 图形架构 之四——图形缓冲区的申请和消费流程及核心类

前言 Android应用的UI显示到Display的过程中,SurfaceFlinger扮演的角色只是“Flinger”,就是定于检查Layer更新,然后计算DirtyRegion,然后将结果推送给底层显示驱动进行显示。 应用层把UI内容 写入到GraphicBuffer,SurfaceFlinger读取数据后 ,合成显示。BufferQueue 是用来管理GraphicBuffer的 一、生产者消费者模型 对GraphicBuffer的管理 使用的是生产者消费者模型,app 产生数据,通知SurfaceF

薛瑄的博客 7692

Spring Cloud Stream多RabbitMQ实例配置时报错no default binder has been set

当前Spring Cloud Rabbit的版本为2.1.2 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> <version>2.1.2.RELEASE</version> </dependency&..

北辰 3594

从MySQL到数据仓库:手把手教你用Airflow实现自动化ETL流水线

本文详细介绍了如何利用Airflow构建从MySQL到数据仓库的自动化ETL流水线,涵盖增量抽取策略、PySpark转换优化和数据质量监控等实战细节。特别适合中小规模企业构建高效数据仓库,提升数据处理效率和质量。

rnn9storyteller的博客 829

A default binder has been requested, but there is no binder available

内容: org.springframework.context.ApplicationContextException: Failed to start bean ‘outputBindingLifecycle’; nested exception is java.lang.IllegalArgumentException: A default binder has been requested,...

weixin_43262676的博客 6984

使用Avalonia跨Linux平台

Avalonia类似使用WPF的技术方法来开发,所以,需要会使用WPF,其中的一些语法和写法与WPF有所区别,但是他们相差不大,会WPF的话,基本上可以看看文档后,完全掌握Avalonia的使用,从而达到跨平台开发的任务。其实写法有些不一样,可以参考官网的说明,进行修改。2. 安装完成后,重启VS2022,我们可以看到1和2,其中1是使用MVVM模式开发,2是普通模式开发,我们选择2,建立项目。9.直接双击粉红色的文件,进行安装,输入密码,但是美中不足的是,好像没有图标,图标似乎需要单独去设置。

故里2130 1万+

BPMN-JS :修改节点“Change Type”事件类型

修改路径:node_modules\bpmn-js\lib\features\replace\ReplaceOptions.js。

TaylorY的博客 680

项目启动的小问题

错误提示:没有默认的绑定 Failed to start bean ‘outputBindingLifecycle’; nested exception is java.lang.IllegalStateException: A default binder has been requested, but there is more than one binder available for ‘org.springframework.cloud.stream.messaging.DirectWithAttr

weixin_43824218的博客 2814

TI AWR2944毫米波雷达开发板开箱:用官方Demo快速上手3D点云与热图生成

本文详细介绍了TI AWR2944毫米波雷达开发板的开箱与实战应用,包括硬件准备、软件开发环境搭建、Demo固件刷写与配置、实时可视化与数据解析等全流程指南。通过官方Demo快速上手3D点云与热图生成,帮助开发者高效掌握毫米波雷达技术在工业检测、智能交通等领域的应用。

weixin_42627853的博客 310

spring还有这种编码?A default binder has been requested, but there is no binder available

A default binder has been requested, but there is no binder available

chingee的博客 2933

什么是以太网链路聚合

以太网链路聚合技术通过将多个物理端口捆绑成逻辑端口,可显著提升网络性能。该技术能增加总带宽(各链路带宽之和)、提高可靠性(故障秒级切换)并实现智能负载分担。主要分为手工模式和基于LACP协议的动态模式,后者能检测链路故障更可靠。配置时需确保接口参数一致、模式匹配,适用于核心交换、服务器接入等场景。华为设备通过创建Eth-Trunk接口、指定LACP模式并添加成员接口即可完成部署。这项成熟技术能以低成本解决带宽瓶颈和可靠性问题,是构建高速稳定网络的关键方案。

lai_2020的博客 675

“华为杯”研究生数学建模竞赛2020年-【华为杯】B题:汽油辛烷值优化建模(附优秀论文)

摘 要:本文通过机器学习算法和数据挖掘技术,建立了汽油辛烷值(RON)损失的预测模型,在保证汽油产品脱硫效果的前提下,以降低汽油辛烷值损失在30%以上为目标,给出每个样本的优化操作条件。针对第一问,对285号和313号原始数据用给定的数据处理规范进行预处理,对每一列变量求期望,得到最终的数据补充到相应的样本编号。针对第二问,首先对数据样本按照最大最小限幅以及拉依达法则进行列变量清洗,通过两轮特征筛选确定变量:结合处理后的数据,针对产品中硫含量、RON损失值用。

getusushu的博客 1251

IllegalArgumentException: A default binder has been requested, but there is no binder available

错误日志: Error starting ApplicationContext. To display the conditions report re-run your application with ‘debug’ enabled. 2019-04-18 19:03:02.888 ERROR 8392 — [ main] o.s.boot.SpringApplicatio...

勒斯 6264

Python 爬虫实战:社交媒体(Facebook)评论数据抓取与情感分析

在当今数字化时代,社交媒体平台如 Facebook 已成为人们日常生活中不可或缺的一部分。它不仅是人们分享生活点滴、交流思想的场所,也为企业和研究人员提供了丰富的数据资源。通过分析社交媒体上的评论数据,我们可以了解用户的情感倾向、产品反馈以及社会热点话题等。本文将详细介绍如何使用 Python 爬虫技术抓取 Facebook 上的评论数据,并进行情感分析。这不仅是一次技术实战,更是一次数据探索之旅。

yansideyucsdn的博客 672

Spring Cloud Strem - Swagger: A default binder has been requested, but there is no binder available

Spring Cloud Strem swagger A default binder has been requested, but there is no binder available

no_away的博客 1215

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

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

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

A default binder has been requested, but there is no binder available(依赖引入有误)

场景:springcloud集成配置中心引入bus。解决的方式:逐个对依赖注释查看报错。

buwenkezhi的博客 585

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

【kubernetes v1.21】(kube-scheduler 5)kube-scheduler API类型、配置、工具与Binder

Part 5: kube-scheduler API类型、配置、工具与Binder超深度分析

zhonglinzhang 240

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Android 12 S WindowManager解读之从dumpsys window windows看window

();;();;();执行adb shell dumpsys window windows 如下:rootTaskId=1(根Taskid) mSession=Session{e98843e 2512:u0a10120} mClient=android.os.BinderProxy@64c3da9appop=NONEmcc?mcc?

weixin_41028555的博客 4864

Android 7系统网络(五)Framework层(上)—ConnectivityService核心机制

ConnectivityService 是 Framework 层最核心的网络服务,负责管理系统中所有网络连接的状态。如果把 Android 网络比作一座城市,ConnectivityService 就是交通调度中心——它决定哪个网络是"默认网络"、何时切换网络、如何处理应用的网络请求。源码路径职责说明管理 NetworkAgent维护所有活跃网络连接(WiFi、移动数据、以太网等)的代理评分与选择比较各网络的评分,决定默认网络处理 NetworkRequest应用请求特定类型网络时的分配。

AfinalStone的专栏 220

Android14 WMS-窗口绘制之relayoutWindow流程(二)-Server端

本文接着如下文章往下讲然后就到了Server端WMS的核心实现方法relayoutWindow里。

weixin_41028555的博客 2347

Android oom_adj 更新原理(androidU)

若有前台服务,并且adj 大于PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ(低于由top进程转移到前台进程)并且,最后一次是top的时间+最长的间隔(TOP_TO_FGS_GRACE_DURATION,默认为15秒,)大于现在的时间,也就说从top 级别的时间变成前台进程的时间在15秒以内;系统根据进程组建的状态来决定每个进程的优先级adj 值,然后再根据一定的策略选择优先级低的进程kill,以此类推,通过回收预期的系统资源来保证系统的正常运转。不含任何活动应用组件的进程。

huibin147852369的专栏 2132

ASP.NET MVC 执行流程深度解析:从路由匹配到视图渲染的可调试全链路

ASP.NET MVC 是一种基于约定的 Web 应用开发框架,其核心价值在于显式暴露请求处理的完整生命周期——包括路由解析、模型绑定、动作执行、过滤器调度与视图渲染五大阶段。这种‘契约显性化’设计使开发者能精准定位 404/500 错误根因,尤其在混合架构(如 MVC + Minimal API)或老旧系统升级场景中,成为排查中间件堆叠导致的隐性时序问题的关键能力。技术价值体现在可调试性、组件级可控性与跨版本稳定性上,广泛应用于企业级遗留系统重构、高可靠性后台管理平台及需要强契约约束的 B2B 接口服务。

dejz8829的专栏 517

AOSP linux环境配置及其编译方法

linux环境配置,android源码环境搭建

yimelancholy的博客 4501

Android 7系统休眠唤醒(三)关机_重启全链路—ShutdownThread到kernel_power_off

关机流程是一个"有序拆除"的过程,而非简单的"拉闸断电"。向所有应用广播关机通知AMS 终止所有 Activity 和进程PackageManager 保存包状态系统服务按依赖顺序关闭vold 安全卸载文件系统并 sync调用内核接口断电整个过程确保:数据不丢失、文件系统不损坏、服务正常断开连接。下一篇Android 7系统休眠唤醒(四)休眠唤醒与开关机—核心差异深度对比。

AfinalStone的专栏 215
上一篇: 垃圾收集器与内存分配策略
下一篇: 取物资问题
炒栗子不加糖
博客等级 码龄10年 68粉丝 123原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值