浅谈Android AsyncTask内存安全的一种使用方式

问题

内部类和内部匿名类会导致内存泄漏,所以很多时候异步代码写的很多。之后一直在想,异步代码到底应该怎么写。怎么才是规范的写法。怎么才是简洁的写法。

思路

以一个弱引用的接口作为主线程与子线程交流的桥梁。

代码

WeakTask.java

public class WeakTask<T> extends AsyncTask<Void, Void, T> {

  private WeakReference<OnWeakTaskListener<T>> listenerReference;

  public WeakTask(OnWeakTaskListener<T> listener){
    this.listenerReference = new WeakReference<>(listener);
  }
  @Override
  protected T doInBackground(Void... voids) {
    if (listenerReference.get() != null) {
      return listenerReference.get().middle();
    }else{
      return null;
    }
  }

  @Override
  protected void onPreExecute() {
    super.onPreExecute();
    if (listenerReference.get() != null) {
      listenerReference.get().before();
    }
  }

  @Override
  protected void onPostExecute(T t) {
    super.onPostExecute(t);
    if (listenerReference.get() != null && t != null){
      listenerReference.get().after(t);
    }
  }
}

OnWeakTaskListener

public interface OnWeakTaskListener<T> {

  void before();

  T middle();

  void after(T t);
}

使用---->LoginActivity.java

public class LoginActivity extends AppCompatActivity implements View.OnClickListener {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.login);
    initLayout();
  }

  private void initLayout(){
    findViewById(R.id.btn_login).setOnClickListener(this);
  }

  @Override
  public void onClick(View view) {
    if (view.getId() == R.id.btn_login){
      new WeakTask<Integer>(new LoginWeakTaskListener()).execute();
    }
  }

  private class LoginWeakTaskListener implements OnWeakTaskListener<Integer>{

    @Override
    public void before() {
       ...开始前
    }

    @Override
    public Integer middle() {
       ...内部执行
    }

    @Override
    public void after(Integer integer) {
       ...结果返回后处理
    }
  }
}

结论

这几天一直在看rxJava,也一直在思考为什么要学习rxJava,当然,我感觉既然美其名曰观察者模式,那么它应该解决的问题主要在于,让主线程中显示的数据随着子线程中的数据去刷新,之前看过Android官方的mvvm好像是使用了rxJava,尝试着使用了rxJava感觉不到任何优势可言。如果后面有时间,会深入研究一下观察者模式,之后再看看rxJava与rxAndroid,最近又到了秋招的时候,又一次面临求职的难题。。。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解Spring/Spring boot异步任务编程WebAsyncTask

    今天一起学习下如何在Spring中进行异步编程.我们都知道,web服务器处理请求 request 的线程是从线程池中获取的,这也不难解释,因为当web请求并发数非常大时,如何一个请求进来就创建一条处理线程,由于创建线程和线程上下文切换的开销是比较大的,web服务器最终将面临崩溃.另外,web服务器创建的处理线程从头到尾默认是同步执行的,也就是说,假如处理线程A负责处理请求B,那么当B没有 return 之前,处理线程A是不可以脱身去处理别的请求的,这将极大限制了web服务器的并发处理能力. 因此

  • Android使用AsyncTask加载图片的操作流程

    加载图片基本操作 一.创建AsyncTask子类 将ImageView的弱引用设置为成员变量,创建构造函数传入ImageView对象. 调用指定大小解析Bitmap方法. 因为是弱引用,所以必须判断引用是否被回收.如果异步任务完成前,用户离开Activity或者设置发生改变,ImageView也可能不存在. class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> { private final WeakReference&

  • Android使用AsyncTask下载图片并显示进度条功能

    在Android中实现异步任务机制有两种方式,Handler和AsyncTask.这篇文章给大家介绍Android使用AsyncTask下载图片并显示进度条功能. AsyncTask下载图片并显示下载进度,异步类AsyncTask配合进度条,简练! public class AsyncTaskActivity2 extends Activity { private Button btnDown;//图片框 private ImageView ivImage;//图片URL private sta

  • Android AsyncTask的优缺点详解

    1.Asynctask简介 1.1 使用方法简介 Asynctask作为Android的基础之一,怎么使用就不多讲解了,网上到处都是教程,建议查看Android官方API文档:https://developer.android.google.cn/reference/android/os/AsyncTask.html 这里只实现一个小Demo程序,供大家赏玩: 界面: 这个程序其实特别简单,就是两个按钮,点击分别用来测试AysncTask和Handler两种模式的实现,点击后会有相应的Log提示

  • Spring Boot 使用WebAsyncTask异步返回结果

    在Spring Boot中(Spring MVC)下请求默认都是同步的,一个请求过去到结束都是由一个线程负责的,很多时候为了能够提高吞吐量,需要将一些操作异步化,除了一些耗时的业务逻辑可以异步化,我们的查询接口也是可以做到异步执行. 一个请求到服务上,是用的web容器的线程接收的,比如线程http-nio-8084-exec-1 我们可以使用WebAsyncTask将这个请求分发给一个新的线程去执行,http-nio-8084-exec-1可以去接收其他请求的处理.一旦WebAsyncTask返

  • Android AsyncTask的缺陷和问题总结

    Android  AsyncTask的缺陷和问题总结 在Android开发中,AsyncTask可以使得用户避免直接使用Thread类和Handler 来处理后台操作,适用于需要异步处理数据并将数据更新到界面上的情况.AsyncTask适用于后台操作只有几秒的短时操作.但是AsyncTask本身存在很多糟糕的问题,如果使用中不注意,将会影响程序的健壮性. 1.生命周期 很多开发者会认为一个在Activity中创建的AsyncTask会随着Activity的销毁而销毁.然而事实并非如此.Async

  • Android带进度条的下载图片示例(AsyncTask异步任务)

    为什么要用异步任务? 在Android中只有在主线程才能对ui进行更新操作,而其它线程不能直接对ui进行操作 android本身是一个多线程的操作系统,我们不能把所有的操作都放在主线程中操作 ,比如一些耗时操作.如果放在主线程中 会造成阻塞 而当阻塞事件过长时 系统会抛出anr异常.所以我们要使用异步任务.android为我们提供了一个封装好的组件asynctask. AsyncTask可以在子线程中更新ui,封装简化了异步操作.适用于简单的异步处理.如果多个后台任务时就要使用Handler了

  • Android 中使用 AsyncTask 异步读取网络图片

     1.新建Android工程AsyncLoadPicture 新建布局文件activity_main.xml主界面为一个GridView,还有其子项布局文件gridview_item.xml 2.功能主界面MainActivity.java,主代码如下 package com.example.asyncloadpicture; import java.util.ArrayList; import android.app.Activity; import android.content.Conte

  • Android中使用AsyncTask实现下载文件动态更新进度条功能

    1. 泛型 AysncTask<Params, Progress, Result> Params:启动任务时传入的参数,通过调用asyncTask.execute(param)方法传入. Progress:后台任务执行的进度,若不用显示进度条,则不需要指定. Result:后台任务结束时返回的结果. 2. 重要方法 doInBackground(Params... params):必须重写的方法,后台任务就在这里执行,会开启一个新的线程.params为启动任务时传入的参数,参数个数不定. on

  • 浅谈Android AsyncTask内存安全的一种使用方式

    问题 内部类和内部匿名类会导致内存泄漏,所以很多时候异步代码写的很多.之后一直在想,异步代码到底应该怎么写.怎么才是规范的写法.怎么才是简洁的写法. 思路 以一个弱引用的接口作为主线程与子线程交流的桥梁. 代码 WeakTask.java public class WeakTask<T> extends AsyncTask<Void, Void, T> { private WeakReference<OnWeakTaskListener<T>> listen

  • 浅谈Android中多线程切换的几种方法

    我们知道,多线程是Android开发中必现的场景,很多原生API和开源项目都有多线程的内容,这里简单总结和探讨一下常见的多线程切换方式. 我们先回顾一下Java多线程的几个基础内容,然后再分析总结一些经典代码中对于线程切换的实现方式. 几点基础 多线程切换,大概可以切分为这样几个内容:如何开启多个线程,如何定义每个线程的任务,如何在线程之间互相通信. Thread Thread可以解决开启多个线程的问题. Thread是Java中实现多线程的线程类,每个Thread对象都可以启动一个新的线程,注

  • 浅谈Android Studio 解析XML的三种方法

    一丶概述 文件解析要求,json解析和xml解析,前面文章说过Json转实体类,这里就说说解析XML 内容: Android Studio 解析XML常见的三种方式:DOM PULL SAX (实现XML转实体类并打印输出) 效果演示: 二丶正文 SAX(Simple API for XML) 使用流式处理的方式,它并不记录所读内容的相关信息.它是一种以事件为驱动的XML API,解析速度快,占用内存少.使用回调函数来实现. 缺点是不能倒退. DOM(Document Object Model)

  • 浅谈C#中Md5和Sha1两种加密方式

    1.新建控制台应用程序 2.新建类 EncryptHelper.cs public static class EncryptHelper { /// <summary> /// 基于Md5的自定义加密字符串方法:输入一个字符串,返回一个由32个字符组成的十六进制的哈希散列(字符串). /// </summary> /// <param name="str">要加密的字符串</param> /// <returns>加密后的十六

  • 浅谈Android性能优化之内存优化

    1.Android内存管理机制 1.1 Java内存分配模型 先上一张JVM将内存划分区域的图 程序计数器:存储当前线程执行目标方法执行到第几行. 栈内存:Java栈中存放的是一个个栈帧,每个栈帧对应一个被调用的方法.栈帧包括局部标量表, 操作数栈. 本地方法栈:本地方法栈主要是为执行本地方法服务的.而Java栈是为执行Java方法服务的. 方法区:该区域被线程共享.主要存储每个类的信息(类名,方法信息,字段信息等).静态变量,常量,以及编译器编译后的代码等. 堆:Java中的堆是被线程共享的,

  • 浅谈Android中AsyncTask的工作原理

    概述 实际上,AsyncTask内部是封装了Thread和Handler.虽然AsyncTask很方便的执行后台任务,以及在主线程上更新UI,但是,AsyncTask并不合适进行特别耗时的后台操作,对于特别耗时的任务,个人还是建议使用线程池.好了,话不多说了,我们先看看AsyncTask的简单用法吧. AsyncTask使用方法 AsyncTask是一个抽象的泛型类.简单的介绍一下它的使用方式代码如下: package com.example.huangjialin.myapplication;

  • 浅谈Android Studio 3.0 工具新特性的使用 Android Profiler 、Device File Explorer

    前言: 其实 studio3.0的工具大家也已经使用过一段时间了,自己呢,就是从bate版开始使用的,我觉得比较好用的几个地方.就几个,可能还没用到其他的精髓. 但我觉的这个两个功能对我是比较实用的.好那么下面就给大家介绍一下吧. 正文: 话不多说咱们直接上图吧.(个人比较喜欢看图说话) 第一个(Android Profiler)我要介绍的就是这个了.(先看一下效果"震撼一下") (图-1) (图-2) (图-3) (厉害不厉害,牛逼不牛逼)那么我们怎么来操作这个工具呢,来咱们接着看图

  • 浅谈Android中Service的注册方式及使用

    Service通常总是称之为"后台服务",其中"后台"一词是相对于前台而言的,具体是指其本身的运行并不依赖于用户可视的UI界面,因此,从实际业务需求上来理解,Service的适用场景应该具备以下条件: 1.并不依赖于用户可视的UI界面(当然,这一条其实也不是绝对的,如前台Service就是与Notification界面结合使用的): 2.具有较长时间的运行特性. 1.Service AndroidManifest.xml 声明 一般而言,从Service的启动方式上

  • 浅谈Android Studio3.6 更新功能

    前言 下载google CodeLab的程序时,提示要更新3.6版本才能运行程序,于是更新了一下,看看有什么新功能. 界面设计工具 这次更新了一些设计工具,比如Layout Editor 和 Resource Manager. 现在,在XML或设计工具的颜色选择器中,Android Studio会在您的应用程序中填充颜色资源,以便您快速选择和替换颜色资源值. 拆分视图并放大设计编辑器 设计编辑器(例如,布局编辑器和导航编辑器)现在提供一个拆分视图,使您可以同时查看UI的"设计"视图和&

  • 浅谈Android中适配器的notifyDataSetChanged()为何有时不刷新

    学过Android开发的人都知道,ListView控件在开发中经常遇到,并且ListView通常结合Adapter适配器来进行数据显示和数据更新操作.姑且假设数据存储在名为dataList的成员变量中.数据操作无非是增加数据.删除数据这两种主要的操作,而当数据有所变化时,为了及时向用户提供更新后的数据,我们知道需要在数据更新后调用适配器的notifyDataSetChanged()方法,来显示更新后的数据.殊不知,该方法并非百试不爽,在此我们便来讨论下具体的原因,其实本质是关注内存的分配情况.

随机推荐