首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >简单了解下Spring中的各种Aware接口实现依赖注入

简单了解下Spring中的各种Aware接口实现依赖注入

原创
作者头像
codetrend
发布于 2024-08-03 09:04:27
发布于 2024-08-03 09:04:27
2230
举报
文章被收录于专栏:Spring全攻略Spring全攻略

你好,这里是codetrend专栏“Spring6全攻略”。

在Spring框架中,Aware接口是一组用于提供特定资源或环境信息的回调接口。这些接口被设计用来允许Bean获取对Spring容器或其他相关资源的引用,并在需要时进行适当的处理。

Aware接口的设计是为了让Bean能够感知到其所处的环境并与之交互。通过实现这些接口,Bean可以获取对Spring容器或其他相关资源的引用,从而能够更好地适应和利用所处的环境。

使用场景

  • 获取Spring容器的引用:ApplicationContextAware接口可以让Bean获取对Spring容器的引用,从而能够访问容器中的其他Bean或执行一些特定的操作。
  • 资源加载和处理:BeanClassLoaderAware和ResourceLoaderAware接口可以让Bean获取类加载器和资源加载器的引用,用于加载资源文件或进行类加载操作。
  • 事件发布和消息处理:ApplicationEventPublisherAware和MessageSourceAware接口可以让Bean获取事件发布器和消息源的引用,用于发布事件或处理国际化消息。
  • Web环境处理:ServletConfigAware和ServletContextAware接口可以让Bean获取对Servlet配置和上下文的引用,在Web应用中进行特定的处理。

Aware接口

名称

注入的依赖

ApplicationContextAware(常用)

声明的 ApplicationContext。

ApplicationEventPublisherAware

包含的 ApplicationContext 的事件发布器。

BeanClassLoaderAware

用于加载 bean 类的类加载器。

BeanFactoryAware(常用)

声明的 BeanFactory。

BeanNameAware

声明 bean 的名称。

LoadTimeWeaverAware

在加载时处理类定义的已定义织入器。

MessageSourceAware

配置用于解析消息的策略(支持参数化和国际化)。

NotificationPublisherAware

Spring JMX 通知发布器。

ResourceLoaderAware

配置的加载器,用于低级别访问资源。

ServletConfigAware

容器运行的当前 ServletConfig。仅在 web 感知的 Spring ApplicationContext 中有效。

ServletContextAware

容器运行的当前 ServletContext。仅在 web 感知的 Spring ApplicationContext 中有效。

ApplicationContextAware 接口

实现这个接口的Bean可以在其初始化时获取到ApplicationContext,从而能够访问Spring容器中的所有Bean及其配置。具体来说,这个接口主要用于需要与Spring上下文进行交互的场景。

例子代码如下:

代码语言:java
AI代码解释
复制
class ContextAwareBean implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    public void showBeanDetails() {
        String[] beanNames = applicationContext.getBeanDefinitionNames();
        System.out.println("Bean names in ApplicationContext:");
        for (String beanName : beanNames) {
            System.out.println(beanName);
        }
    }
}

注意事项:

  • 避免过度依赖ApplicationContext:虽然ApplicationContextAware提供了强大的功能,但应谨慎使用,以避免过度依赖Spring上下文,导致代码难以测试和维护。
  • Bean生命周期:确保在Bean初始化完成后再调用依赖ApplicationContext的方法,否则可能会遇到空指针异常(NullPointerException)。
  • 测试困难:由于ApplicationContextAware直接依赖于Spring容器,在单元测试中模拟这些依赖可能会比较复杂。

ApplicationEventPublisherAware 接口

ApplicationEventPublisherAware接口允许Bean获取到ApplicationEventPublisher实例,以便能够发布事件。通过实现该接口,Bean可以在运行时向应用程序上下文发布自定义事件或标准Spring事件。

例子代码如下:

代码语言:java
AI代码解释
复制
@Getter
class CustomEvent extends ApplicationEvent {

    private final String message;
    public CustomEvent(Object source, String message) {
        super(source);
        this.message = message;
    }

}

/**
 * 事件发布
 */
@Component
class EventPublisherBean implements ApplicationEventPublisherAware {

    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    public void publishCustomEvent(final String message) {
        CustomEvent customEvent = new CustomEvent(this, message);
        applicationEventPublisher.publishEvent(customEvent);
    }
}

/**
 * 事件监听
 */
@Component
class CustomEventListener {
    @EventListener
    public void handleCustomEvent(CustomEvent event) {
        System.out.println("Received custom event - " + event.getMessage());
    }
}

测试代码输出如下:

代码语言:shell
AI代码解释
复制
Received custom event - Hello, Spring Events!

注意事项:

  • 避免过度依赖:尽量将事件发布逻辑与业务逻辑分离,遵循单一职责原则,避免过度依赖Spring的事件机制,从而保持代码的可维护性和可测试性。
  • 异步事件处理:在需要异步处理事件的场景下,可以结合Spring的异步支持(如@Async注解)来提高性能。
  • 事件传播:注意事件的传播范围和生命周期,确保事件发布和处理的顺序和时机符合业务需求。

BeanClassLoaderAware 接口

通过实现这个接口,Bean可以在其生命周期内访问加载它的类加载器,从而进行一些需要类加载器操作的任务。

实现demo如下:

代码语言:java
AI代码解释
复制
/**
 * 说明:BeanClassLoaderAware demo
 * @since 2024/6/13
 * @author sunz
 */
public class ClassLoaderAwareDemo {
    public static void main(String[] args) {
        // 创建一个基于 Java Config 的应用上下文
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppScanConfig.class);
        ClassLoaderAwareBean classLoaderAwareBean = context.getBean(ClassLoaderAwareBean.class);
        classLoaderAwareBean.performClassLoadingTask("org.springframework.beans.factory.BeanClassLoaderAware");
        // 销毁容器
        context.close();
    }
}


@Component
class ClassLoaderAwareBean implements BeanClassLoaderAware {

    private ClassLoader classLoader;

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
        System.out.println("ClassLoader has been set.");
    }

    public void performClassLoadingTask(String clsName) {
        try {
            // 例如动态加载一个类
            Class<?> loadedClass = classLoader.loadClass(clsName);
            System.out.println("Class loaded: " + loadedClass.getName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

输出结果如下:

代码语言:shell
AI代码解释
复制
ClassLoader has been set.
Class loaded: org.springframework.beans.factory.BeanClassLoaderAware

注意事项:

  • 避免过度使用:虽然BeanClassLoaderAware接口提供了类加载器的访问能力,但应谨慎使用,避免在业务逻辑中过度依赖类加载器,保持代码的简洁和可维护性。
  • 类加载器隔离:在复杂的应用场景中,特别是涉及模块化或插件化的系统中,不同模块可能会使用不同的类加载器。确保正确理解和管理类加载器的隔离和作用范围。
  • 错误处理:在动态加载类或资源时,应注意处理可能的异常情况,例如类未找到(ClassNotFoundException)或资源不存在等。

BeanFactoryAware 接口

通过实现这个接口,Bean 可以在自身的生命周期中访问 Spring 容器,从而动态地获取其他 Bean 或者进行一些容器级别的操作。

比如写个策略模式,通过策略动态获取bean就可能用到。

一般场景如下:

  • 动态获取 Bean: 虽然依赖注入已经非常强大,但在某些情况下,可能需要动态获取 Bean。例如,根据运行时条件选择性地创建或获取不同类型的 Bean。
  • 容器级别操作: 有时需要执行一些高级操作,如检查 Bean 的存在性、获取 Bean 的定义信息等。

Demo代码如下:

代码语言:java
AI代码解释
复制
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;
/**
 * 说明:BeanFactoryAware 例子
 * @since 2024/6/13
 * @author sunz
 */
public class BeanFactoryAwareDemo {
    public static void main(String[] args) {
        // 创建一个基于 Java Config 的应用上下文
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppScanConfig.class);
        MyBeanFactoryAware bean = context.getBean(MyBeanFactoryAware.class);
        bean.doSomething();
        // 销毁容器
        context.close();
    }
}


@Component
class MyBeanFactoryAware implements BeanFactoryAware {

    private BeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    public void doSomething() {
        // 现在可以使用 beanFactory 来获取其他的 Bean
        MyService myService = beanFactory.getBean(MyService.class);
        myService.performAction();
    }
}

@Component
class MyService {
    public void performAction() {
        System.out.println("hello world");
    }
}

注意事项:

  • 避免滥用: 过度依赖 BeanFactoryAware 可能导致代码与 Spring 框架紧密耦合,降低代码的可测试性和灵活性。应该尽量使用依赖注入来代替直接访问 BeanFactory。
  • 单例模式: 如果 Bean 是单例的,那么它所持有的 BeanFactory 也是单例的。这意味着同一个 BeanFactory 实例会被多个单例 Bean 共享。

BeanNameAware 接口

实现这个接口的 Bean 对象在被 Spring 容器实例化后,能够获取到自己在容器中的名称。

这在某些情况下可能会非常有用,例如在调试、日志记录或需要根据 Bean 名称执行特定逻辑时。

一般应用场景:

  • 调试和日志记录: 在开发和维护过程中,知道 Bean 的名称可以帮助调试和记录日志。
  • 动态处理逻辑: 某些情况下,业务逻辑可能需要根据 Bean 的名称来进行不同的处理。

demo代码如下:

代码语言:java
AI代码解释
复制
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;

/**
 * 说明: BeanNameAware 例子
 *
 * @author sunz
 * @since 2024/6/13
 */
public class BeanNameAwareDemo {
    public static void main(String[] args) {
        // 创建一个基于 Java Config 的应用上下文
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppScanConfig.class);
        MyBeanNameAware bean = context.getBean(MyBeanNameAware.class);
        bean.setBeanName("hello,jack");
        bean.printBeanName();
        // 销毁容器
        context.close();
    }
}

@Component
class MyBeanNameAware implements BeanNameAware {

    private String beanName;

    @Override
    public void setBeanName(String name) {
        this.beanName = name;
    }

    public void printBeanName() {
        System.out.println("Bean name is: " + beanName);
    }
}

注意事项:

  • 避免过度依赖: 类似于其他 Aware 接口,过度依赖 BeanNameAware 可能导致代码与 Spring 框架紧密耦合,降低代码的可测试性和灵活性。应尽可能使用依赖注入和其他更解耦的设计模式。

LoadTimeWeaverAware 接口

实现这个接口的 Bean 在被 Spring 容器实例化后,能够获取到一个 LoadTimeWeaver 实例。LoadTimeWeaver 是用于在类加载时进行字节码增强的重要机制之一,比如在 AOP(面向切面编程)中动态地织入横切关注点。

代码没什么实际使用场景,开源项目搜索也没发现使用例子,实际使用还是比较少。

不推荐使用,使用AOP还是直接用spring aop即可。

实际使用代码和之前的Aware是一致的,只要实现接口即可。

代码语言:java
AI代码解释
复制
class MyLoadTimeWeaverAware implements LoadTimeWeaverAware {
    private LoadTimeWeaver loadTimeWeaver;
    @Override
    public void setLoadTimeWeaver(LoadTimeWeaver loadTimeWeaver) {
        this.loadTimeWeaver = loadTimeWeaver;
    }
    public void doSomething() {
        // 使用 loadTimeWeaver 进行字节码增强等操作
        // 这里仅作为示例,不进行实际操作
        System.out.println("LoadTimeWeaver is set and can be used now.");
    }
}

MessageSourceAware 接口

MessageSourceAware 是 Spring 框架中的一个接口,用于实现国际化(i18n)的功能。它允许一个 bean 接收 MessageSource 对象,从而能够在应用程序中访问国际化的消息资源。

实现 MessageSourceAware 接口的类可以直接使用 MessageSource 来获取国际化的消息,而不必显式地在其配置中注入 MessageSource bean。

这对于需要频繁访问国际化消息的 bean 非常有用。

例子代码如下:

代码语言:java
AI代码解释
复制
/**
 * 说明:MessageSourceAware demo
 * @since 2024/6/13
 * @author sunz
 */
public class MessageSourceAwareDemo {
    public static void main(String[] args) {
        // 创建一个基于 Java Config 的应用上下文
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppMessageConfig.class);
        GreetingService bean = context.getBean(GreetingService.class);
        String greetingEn = bean.getGreeting("John", Locale.ENGLISH);
        System.out.println(greetingEn); // 输出: Hello, John!
        String greetingZh = bean.getGreeting("李雷", Locale.CHINESE);
        System.out.println(greetingZh); // 输出: 你好, 李雷!
        // 销毁容器
        context.close();
    }
}

/**
 * 配置类
 */
@Configuration
@ComponentScan(basePackages = "io.yulin.learn.spring.s108")
class AppMessageConfig {
    @Bean
    public ResourceBundleMessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("messages");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }
}

/**
 * 服务bean
 */
@Component
class GreetingService implements MessageSourceAware {

    private MessageSource messageSource;

    @Override
    public void setMessageSource(MessageSource messageSource) {
        this.messageSource = messageSource;
    }

    public String getGreeting(String name, Locale locale) {
        return messageSource.getMessage("greeting", new Object[]{name}, locale);
    }
}

其中资源文件如下:

代码语言:xml
AI代码解释
复制
<!-- messages_en.properties -->
greeting=Hello, {0}!
<!-- messages_zh.properties -->
greeting=你好, {0}!

一般情况下使用多语言工具可以进行二次封装,使得使用起来更简洁方便,而不是每次进行注入。

以下是一个封装的例子:

代码语言:java
AI代码解释
复制
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;

import java.util.Locale;

@Component
public class MessageUtils {
    private static MessageSource messageSource;

    // Spring 会自动注入该方法中的参数 messageSource
    public MessageUtils(MessageSource messageSource) {
        MessageUtils.messageSource = messageSource;
    }

    /**
     * 获取国际化消息
     *
     * @param code 消息代码
     * @param args 消息参数
     * @return 国际化消息
     */
    public static String getMessage(String code, Object... args) {
        Locale locale = LocaleContextHolder.getLocale();
        return messageSource.getMessage(code, args, locale);
    }
}

NotificationPublisherAware 接口

NotificationPublisherAware 是 Spring 框架中的一个接口,用于与 JMX(Java Management Extensions)相关的通知机制进行集成。实现该接口的 bean 可以通过 Spring 容器获得一个 NotificationPublisher 实例,从而能够发布 JMX 通知。

在需要发布 JMX 通知的 Spring 管理的 bean 中,实现 NotificationPublisherAware 接口可以方便地获取 NotificationPublisher 并发布通知。这通常用于监控和管理应用程序状态变化,如资源使用情况、性能指标等。

例子代码如下:

代码语言:java
AI代码解释
复制
/**
 * 说明:NotificationPublisherAware  demo
 * @since 2024/6/13
 * @author sunz
 */
public class NotificationPublisherAwareDemo {
    public static void main(String[] args) {
        // 创建一个基于 Java Config 的应用上下文
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppNotifyConfig.class);
        MyManagedBean bean = context.getBean(MyManagedBean.class);
        bean.doSomething();
        // 销毁容器
        context.close();
    }
}
@Configuration
@ComponentScan(basePackages = "io.yulin.learn.spring.s108")
class AppNotifyConfig{
    @Bean
    public MBeanExporter mBeanExporter() {
        MBeanExporter exporter = new MBeanExporter();
        exporter.setRegistrationPolicy(RegistrationPolicy.REPLACE_EXISTING);
        Map<String, Object> beans = new HashMap<>();
        beans.put("bean:name=myManagedBean", myManagedBean());
        exporter.setBeans(beans);
        return exporter;
    }
    @Bean
    public MyManagedBean myManagedBean() {
        return new MyManagedBean();
    }
}

/**
 * 服务bean
 */
@Component
class MyManagedBean extends NotificationBroadcasterSupport implements MyManagedBeanMBean,NotificationPublisherAware {

    private NotificationPublisher notificationPublisher;

    @Override
    public void setNotificationPublisher(NotificationPublisher notificationPublisher) {
        this.notificationPublisher = notificationPublisher;
    }

    @Override
    public void doSomething() {
        // 执行某些操作
        System.out.println("Doing something...");
        // 发布通知
        Notification notification = new Notification(
                "myNotificationType",
                this,
                System.currentTimeMillis(),
                "Something happened!"
        );
        if (this.notificationPublisher != null) {
            notificationPublisher.sendNotification(notification);
        } else {
            // 使用 NotificationBroadcasterSupport 自带的方法
            sendNotification(notification);
        }
    }
}

JMX接收和监听比较复杂,这里只是使用了NotificationPublisher进行推送通知消息。

ResourceLoaderAware 接口

实现 ResourceLoaderAware 接口的类会在其被 Spring 容器管理时自动获得一个 ResourceLoader 实例。通过这个实例,类可以方便地加载各种类型的资源(如文件系统、类路径、URL 等)。

通常在需要访问外部资源(例如文件、配置文件、图片等)的类中,可以实现 ResourceLoaderAware 接口。这比直接依赖 File 或其他资源加载机制更灵活,因为 ResourceLoader 可以处理多种类型的资源路径(如类路径、文件系统路径、URL 等)。

以下是一个简单的示例,展示了如何实现 ResourceLoaderAware 并使用 ResourceLoader 加载文本文件。

代码语言:java
AI代码解释
复制
/**
 * 说明:ResourceLoaderAware   demo
 * @since 2024/6/14
 * @author sunz
 */
public class ResourceLoaderAwareDemo {
    public static void main(String[] args) {
        // 创建一个基于 Java Config 的应用上下文
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppScanConfig.class);
        MyResourceLoaderAwareBean bean = context.getBean(MyResourceLoaderAwareBean.class);
        // 假设 "test.txt" 位于 classpath 路径下
        bean.loadResource("classpath:application.yml");
        // 销毁容器
        context.close();
    }
}
/**
 * 服务bean
 */
@Component
class MyResourceLoaderAwareBean implements ResourceLoaderAware {

    private ResourceLoader resourceLoader;

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    public void loadResource(String location) {
        try {
            Resource resource = resourceLoader.getResource(location);
            BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

ServletConfigAware 接口

实现 ServletConfigAware 接口的类会在其被 Spring 容器管理时自动获得一个 ServletConfig 实例。通过这个实例,类可以方便地获取关于当前 Servlet 的配置信息。

使用demo如下:

代码语言:java
AI代码解释
复制
/**
 * 服务bean
 */
@RestController
@RequestMapping("/test")
public class MyServletConfigAwareBean implements ServletConfigAware {

    private ServletConfig servletConfig;

    @Override
    public void setServletConfig(ServletConfig servletConfig) {
        this.servletConfig = servletConfig;
    }

    @GetMapping("/demo")
    public void printServletInfo() {
        String servletName = servletConfig.getServletName();
        String initParamValue = servletConfig.getInitParameter("myInitParam");
        String contextPath = servletConfig.getServletContext().getContextPath();

        System.out.println("Servlet Name: " + servletName);
        System.out.println("Init Param Value: " + initParamValue);
        System.out.println("Context Path: " + contextPath);
    }
}

实际验证会发现servletConfig报空指针异常,这块是因为没初始化相关的配置导致的。

ServletContextAware 接口

ServletContextAware 接口是 Spring 框架中的一个接口,用于让实现它的类获取当前 Servlet 上下文(ServletContext)的引用。通过实现这个接口,类可以在 Spring 容器初始化时自动获取 Servlet 上下文对象,从而进行一些与 Servlet 相关的操作。

使用demo如下:

代码语言:java
AI代码解释
复制
@RestController
@RequestMapping("/test2")
public class MyServletContextAwareBean implements ServletContextAware {

    private ServletContext servletContext;

    @Override
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    // 可以添加其他方法来使用 servletContext 对象
    @GetMapping("/demo")
    public void printServletInfo() {
        System.out.println("ServletContext: " + servletContext);
        System.out.println("ServletContext name: " + servletContext.getServletContextName());
        System.out.println("ServletContext context path: " + servletContext.getContextPath());
        System.out.println("ServletContext server info: " + servletContext.getServerInfo());
        System.out.println("ServletContext major version: " + servletContext.getMajorVersion());
        System.out.println("ServletContext minor version: " + servletContext.getMinorVersion());
    }
}

ServletContext 常用的场景如下:

  1. 获取上下文路径和真实路径:可以获取当前 web 应用的上下文路径和部署后的真实路径。
  2. 执行一些 Servlet 上下文管理的操作:如获取当前已经初始化的 Servlet、获取 Servlet 的名称等。
  3. 与会话管理相关的操作:可以通过 ServletContext 获取应用的会话管理器,并进行相关的会话操作。

点击话题和专栏可以看更多往期文章。

关于作者

来自一线全栈程序员nine的探索与实践,持续迭代中。

欢迎关注、评论、点赞。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
AsyncTask解析
需要进度更新: onPreExecute() --> doInBackground() --> publishProgress() --> onProgressUpdate() --> onPostExecute()
用户1205080
2019/04/25
6600
Android | AsyncTask基础梳理
AsyncTask. 异步任务 目的:方便后台线程中操作后更新UI 封装并简化了异步操作 实现:Thread和Handler进行了封装 实质:Handler异步消息处理机制 参数是泛型:<Params,Progress,Result> UI操作:onPreExecute,onPostExecute 后台线程操作 doInBackground 输入输出:Params(入),Result(出) 进度显示:onProgressUpdate ANR(Application Not Responding)
凌川江雪
2019/11/12
6340
Android查缺补漏(线程篇)-- AsyncTask的使用及原理详细分析
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8515304.html 一、AsyncTask的使用 AsyncTask是一种轻量级的异步任务类,可以很方便的在线程池中执行异步任务,并且将进度和结果传递给主线程。其底层由Thread+handler实现。 AsyncTask是一个抽象的泛型类,其类的声明如下: public abstract class AsyncTask<Params, Progress, Result> 其中三个泛型
codingblock
2018/03/30
1.1K0
锦囊篇|一文摸懂AsyncTask
一般我们在代码中只用执行excute()的函数,在各个函数流程中给出相对应的操作。
ClericYi
2020/07/24
4500
锦囊篇|一文摸懂AsyncTask
AsyncTask源码深入解析
最近想写一篇关于源码解析的文章,发现AsyncTask代码量不多,可里面的东西却是很值得学习的,所以故那这来“开刀”
HelloJack
2018/08/28
4520
AsyncTask源码深入解析
AsyncTask 使用及封装实践
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/details/57409326
程序员徐公
2018/09/18
9860
AsyncTask 使用及封装实践
Android AsyncTask实现原理和使用技巧分享
我们写App都有一个原则,主线程不能够运行需要占用大量CPU时间片的任务,如大量复杂的浮点运算,较大的磁盘IO操作,网络socket等,这些都会导致我们的主线程对用户的响应变得迟钝,甚至ANR,这些会使应用的用户体验变差,但是有时又的确需要执行这些耗时的任务,那么我们通常可以使用AsyncTask或者new Thread 来处理,这样把任务放入工作线程中执行,不会占用主线程的时间片,所以主线程会及时响应用户的操作,如果使用new Thread来执行任务,那么如果需要中途取消任务执行或者需要返回任务执行结果,就需要我们自己维护很多额外的代码,而AsyncTask是基于concurrent架包提供的并发类实现的,上面的二个需求都已经帮我们封装了,这也是我们选择AsyncTask的原因。
三好码农
2018/09/11
8230
【Android 异步操作】AsyncTask 异步任务 ( 参数简介 | 方法简介 | 使用方法 | AsyncTask 源码分析 )
AsyncTask 构造函数作用 : 创建一个新的异步任务 , 该构造函数必须在 UI 主线程调用 ;
韩曙亮
2023/03/28
9640
asynctask使用_androidstudiohelloworld教程
这是Google Android 开发文档上关于AsyncTask的介绍,大概意思是AsyncTask设计为一个对于Thread和Handle的辅助类,主要让开发者方便的使用UI Thread和后台Thread的操作( 比如在后台线程下载文件,同时要在UI线程更新下载进度 )。同时这不是一个通用的多线程编程框架,他被设计为用于能够在 最多几秒的时间内返回结果的任务。
全栈程序员站长
2022/08/04
3890
Android 多线程的几种方式
如果您的App没有明确指定屏幕方向和configChanges时,当用户旋转屏幕的时候Activity就会重新启动,而这个时候您的异步加载数据的线程可能正在请求网络。当一个新的Activity被重新创建之后,就又重新启动了一个新的任务去请求网络,这样之前的一个异步任务不经意间就泄露了,假设你还在onPostExecute写了一些其他逻辑,这个时候就会发生意想不到异常。
码客说
2019/10/22
8590
Android多线程:AsyncTask使用教程(含实例讲解)
前言 多线程的应用在Android开发中是非常常见的,常用方法主要有: 继承Thread类 实现Runnable接口 Handler AsyncTask HandlerThread 今天,我将献上一份AsyncTask使用教程,希望大家会喜欢 Carson带你学多线程系列 基础汇总 Android多线程:基础知识汇总 基础使用 Android多线程:继承Thread类使用(含实例教程) Android多线程:实现Runnable接口使用(含实例教程) 复合使用 Android多线程:As
Carson.Ho
2022/03/25
9380
Android多线程:AsyncTask使用教程(含实例讲解)
AsyncTask源码解析
导语 AsyncTask对Android开发者来说并不陌生,当有耗时任务并涉及UI交互,AsyncTask可是处理异步任务的利器。AsyncTask使用也很方便,开发的时候多留意不要内存泄漏,一般处理方法就是把AsyncTask写成静态内部类的形式。 使用方法 new AsyncTask<Integer, Integer, Boolean>() { private int NUM = 0; @Override protected void
用户1269200
2018/02/01
8370
Android 多线程-----AsyncTask详解
本篇随笔将讲解一下Android的多线程的知识,以及如何通过AsyncTask机制来实现线程之间的通信。
杨奉武
2018/09/27
6360
Android 多线程-----AsyncTask详解
【Android 电量优化】电量优化 ( JobScheduler | JobService | AsyncTask )
① 获取 JobScheduler 服务 : 从 Context 对象中 , 调用 getSystemService 方法跨进程获取 ;
韩曙亮
2023/03/28
1.4K0
Android 多线程:这是一份详细的AsyncTask使用教程
下面,我将用1个实例讲解 具体如何使用 `AsyncTask`
Carson.Ho
2019/02/22
1.4K1
安卓异步任务AsyncTask
       Android4.0之后,网络访问这些都是要放在自己开的线程里,然后在主线程里进行访问的。就我所知的有两种方法。一种是自己new一个线程,然后通过Handler机制进行访问;另外一种是用异步任务AsyncTask的方法。
SmileNicky
2019/01/17
5230
Android开发笔记(四十九)异步任务处理AsyncTask
Thread+Handler方式虽然能够实现多线程的通信处理,但是写起代码来颇为繁琐,所以Android提供了AsyncTask这样一个轻量级的异步任务类,其内部封装好Thread+Handler,方便了码农的工作,类似已封装好的多线程处理类还有IntentService(具体见《Android开发笔记(四十一)Service的生命周期》)。AsyncTask适用于HTTP通信,包括下载、http调用等等。 AsyncTask是个模板类(AsyncTask<Params, Progress, Result>),继承它的新类需要指定模板的参数类型,模板参数说明如下: Params : 任务启动时的输入参数,比如http访问的url、请求参数等等。可设置为String类型或者自定义的数据结构 Progress : 任务执行的进度。可设置为Integer类型 Result : 任务执行完的结果。可设置为String类型或者自定义的数据结构 下面是要重写的方法,不能直接调用: doInBackground : 异步处理操作都放在该方法中,params参数对应execute方法的输入参数。该方法运行于分线程,所以不能操作UI,其他方法都能操作UI onPreExecute : 在doInBackground执行之前调用 onProgressUpdate : doInBackground方法中调用publishProgress时会触发该方法,通常用于处理过程中刷新进度条 onPostExecute : 在doInBackground执行完毕时调用,通常用于处理完毕后刷新展示页面 onCancelled : doInBackground方法中调用cancel时会触发该方法 下面是可直接调用的方法: execute : 开始执行异步处理任务。 executeOnExecutor : 以指定线程池模式开始执行任务。THREAD_POOL_EXECUTOR表示异步线程池,SERIAL_EXECUTOR表示同步线程池。默认是SERIAL_EXECUTOR。 publishProgress : 更新进度。该方法只能在doInBackground方法中调用,调用后会触发onProgressUpdate方法。 cancel : 取消任务。该方法调用后,doInBackground的处理立即停止,并且接着调用onCancelled方法,而不会调用onPostExecute方法。 get : 获取处理结果。 getStatus : 获取任务状态。PENDING表示还未执行,RUNNING表示正在执行,FINISHED表示执行完毕 isCancelled : 判断该任务是否取消。true表示取消,false表示未取消
aqi00
2019/01/18
1.1K0
Android多线程-AsyncTaskyi(一)
今天分析android的异步线程类HandlerThread与IntentService,它们都是android系统独有的线程类,而android中还有另一个比较重要的异步线程类AsyncTask。本文我们就来分析AsyncTask。
用户9253515
2021/12/08
7310
android异步任务asyntask详解
在Android中实现异步任务机制有两种方式,Handler和AsyncTask。 Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更新,这种方式对于整个过程的控制比较精细,但也是有缺点的,例如代码相对臃肿,在多个任务同时执行时,不易对线程进行精确的控制。关于Handler的相关知识,前面也有所介绍,不清楚的朋友们可以参照一下。 为了简化操作,Android1.5提供了工具类android.os.AsyncTask,它使创建异步任务变得
xiangzhihong
2018/01/30
1.1K0
android异步任务asyntask详解
AsyncTask和Handler对比
1 ) AsyncTask实现的原理,和适用的优缺点 AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程. 使用的优点: l  简单,快捷 l  过程可控 使用的缺点: l  在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来. 2 )Handler异步实现的原理和适用的优缺点 在Handler 异步实现时,涉及到 Handler, Looper,
欢醉
2018/01/22
1.3K0
推荐阅读
相关推荐
AsyncTask解析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档