• App调试内存泄露之Context篇(下)-App调试内存泄露之Context篇(下)


    接着《Android学习系列(36)--App调试内存泄露之Context篇(上)》继续分析。

    5. AsyncTask对象

        我N年前去盛大面过一次试,当时面试官极力推荐我使用AsyncTask等系统自带类去做事情,当然无可厚非。

        但是AsyncTask确实需要额外注意一下。它的泄露原理和前面Handler,Thread泄露的原理差不多,它的生命周期和Activity不一定一致。

        解决方案是:在activity退出的时候,终止AsyncTask中的后台任务。

        但是,问题是如何终止?

        AsyncTask提供了对应的API:public final boolean cancel (boolean mayInterruptIfRunning)。

        它的说明有这么一句话:

    1

    2

    // Attempts to cancel execution of this task. This attempt will fail if the task has already completed, already been cancelled, or could not be cancelled for some other reason.

    // If successful, and this task has not started when cancel is called, this task should never run. If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.

        cancel是不一定成功的,如果正在运行,它可能会中断后台任务。怎么感觉这话说的这么不靠谱呢?

        是的,就是不靠谱。

        那么,怎么才能靠谱点呢?我们看看官方的示例:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {

         protected Long doInBackground(URL... urls) {

             int count = urls.length;

             long totalSize = 0;

             for (int i = 0; i < count; i++) {

                 totalSize += Downloader.downloadFile(urls[i]);

                 publishProgress((int) ((i / (float) count) * 100));

                 // Escape early if cancel() is called

                 // 注意下面这行,如果检测到cancel,则及时退出

                 if (isCancelled()) break;

             }

             return totalSize;

         }

         protected void onProgressUpdate(Integer... progress) {

             setProgressPercent(progress[0]);

         }

         protected void onPostExecute(Long result) {

             showDialog("Downloaded " + result + " bytes");

         }

     }

      官方的例子是很好的,在后台循环中时刻监听cancel状态,防止没有及时退出。

          为了提醒大家,google特意在AsyncTask的说明中撂下了一大段英文:

    1

    // AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent pacakge such as Executor, ThreadPoolExecutor and FutureTask.

        可怜我神州大陆幅员辽阔,地大物博,什么都不缺,就是缺对英语阅读的敏感。

        AsyncTask适用于短耗时操作,最多几秒钟。如果你想长时间耗时操作,请使用其他java.util.concurrent包下的API,比如Executor, ThreadPoolExecutor 和 FutureTask.

        学好英语,避免踩坑!

    6. BroadcastReceiver对象

        ... has leaked IntentReceiver ... Are you missing a call to unregisterReceiver()?

  • 相关阅读:
    论文复现
    20199324 2019-2020-2 《网络攻防实践》第12周作业
    20199324 2019-2020-2 《网络攻防实践》第10周作业
    20199324 2019-2020-2 《网络攻防实践》第9周作业
    Android Dalvikvm的学习笔记
    20199324 2019-2020-2 《网络攻防实践》第8周作业
    20199324 2019-2020-2 《网络攻防实践》第7周作业
    445. Add Two Numbers II
    167. Two Sum II
    643. Maximum Average Subarray I
  • 原文地址:https://www.cnblogs.com/freenovo/p/4469777.html
Copyright © 2020-2023  润新知