zoukankan      html  css  js  c++  java
  • 关于最近开发中遇到的问题汇总(二)

    AsyncTask使用的时候遇到了一个小问题

    • 最近的软工实践项目中,在网络请求的时候使用到了AsyncTask异步的方法
    • 队友小超超在使用过程中发现, doInGround()方法中使用的HttpUtil的回调方法一直没办法结束
    • 使得在onPsotExcute()方法有时候回得不到调用,使得UI没有更改
    • 最终无法显示数据
    • 我觉得这个似乎是因为doInGround方法调用的回调函数没办法返回结果值。于是到不了该函数的终点

    了解一下AsyncTask

    • 带着疑问,我去网上找了一些博客
    • 以图了解这个机制

    Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的。

    与Handler对比

    说到AsyncTask,就要与Handler对比
    1.首先AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.

    • 优点:

    简单快捷,并且过程可控

    • 缺点:

    在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来.

    2.然后是Handler
    在Handler 异步实现时,涉及到 Handler, Looper, Message,Thread四个对象,实现异步的流程是主线程启动Thread(子线程)àthread(子线程)运行并生成Message-àLooper获取Message并传递给HandleràHandler逐个获取Looper中的Message,并进行UI变更。

    • 优点:

    结构清晰,功能定义明确。对于多个后台任务时,简单,清晰

    • 缺点:

    在单个后台异步处理时,显得代码过多,结构过于复杂(相对性)

    AsyncTask

    AsyncTask就是一个封装过的后台任务类,顾名思义就是异步任务
    AsyncTask可以使得用户避免直接使用Thread类和Handler 来处理后台操作,适用于需要异步处理数据并将数据更新到界面上的情况。AsyncTask适用于后台操作只有几秒的短时操作。

    • 1.用法

    AsyncTask<Params , Progress , Result>
    Params启动任务执行的输入参数的类型
    Progress后台任务完成的进度
    Result后台执行任务完成后返回结果的类型

    步骤:
    (1).创建AsyncTask子类,并为三个泛型参数指定类型
    如果不需要指定则为void
    (2).实现AsyncTask的方法:
    Params doInBackground(Params...params)后台线程所要完成的任务调用publishProgress(Progress... values)方法更新任务的执行进度
    void onProgressUpdate(Progress... Values)在doInBackground()方法中调用publishProgress(Progress... values)方法更新任务的执行进度后触发该方法

    void onRreExecute()该方法将在执行后台耗时操作前被调用。通常用来完成一些初始化的准备工作,比如在界面上显示进度条等

    void onPostExcute(Result result)在doInBackground(Params...params)完成后调用,并将doInBackground的返回值传给该函数

    (3).调用AsyncTask子类的实例的execute(Params... params)

    必须在UI线程中创建AsyncTask实例
    必须在UI线程中调用execute()
    AsyncTask的onPreExecute()、onPostExecute(Result result)、doInBackground(Params...params)、onProgressUpdate(Progress... Values)方法,不应该有程序员代码调用,而是由Android系统负责调用

    每个AsyncTask只能被执行一次,多次调用会引发异常

    (1).生命周期

    很多开发者会认为一个在Activity中创建的AsyncTask会随着Activity的销毁而销毁。然而事实并非如此。AsyncTask会一直执行, 直到doInBackground()方法执行完毕。然后,如果 cancel(boolean)被调用, 那么onCancelled(Result result) 方法会被执行;否则,执行onPostExecute(Result result) 方法。如果我们的Activity销毁之前,没有取消 AsyncTask,这有可能让我们的AsyncTask崩溃(crash)。因为它想要处理的view已经不存在了。所以,我们总是必须确保在销毁活动之前取消任务。总之,我们使用AsyncTask需要确保AsyncTask正确地取消。

    另外,即使我们正确地调用了cancle() 也未必能真正地取消任务。因为如果在doInBackgroud里有一个不可中断的操作,比如BitmapFactory.decodeStream(),那么这个操作会继续下去。

    (2).内存泄漏

    如果AsyncTask被声明为Activity的非静态的内部类,那么AsyncTask会保留一个对创建了AsyncTask的Activity的引用。如果Activity已经被销毁,AsyncTask的后台线程还在执行,它将继续在内存里保留这个引用,导致Activity无法被回收,引起内存泄露。

    (3).结果丢失

    屏幕旋转或Activity在后台被系统杀掉等情况会导致Activity的重新创建,之前运行的AsyncTask会持有一个之前Activity的引用,这个引用已经无效,这时调用onPostExecute()再去更新界面将不再生效。

    (4).并行还是串行

    在Android 1.6之前的版本,AsyncTask是串行的,在1.6至2.3的版本,改成了并行的。在2.3之后的版本又做了修改,可以支持并行和串行,当想要串行执行时,直接执行execute()方法,如果需要并行执行,则要执行executeOnExecutor(Executor)。

    结语

    怎么感觉问题还是没有解决
    但是模糊的感觉,主要原因在于数据没获取完的情况下,线程被中断了?
    Orz

  • 相关阅读:
    Eclipse远程调试,服务器为linux的配置
    关于javascript代码执行时间的计算
    Java编程中容易疏忽的知识点
    为什么要开发自己的框架、平台或插件
    算法在计算中的作用
    程序员的自豪感
    iOS,Objective-C Runtime
    iOS,本地化(国际化)字符
    iOS,应用崩溃日志分析
    iOS,信息加解密
  • 原文地址:https://www.cnblogs.com/csming1995/p/6159524.html
Copyright © 2011-2022 走看看