如果用lambda实现Handler的Callback接口来处理消息会不会造成内存泄漏呢?

来源:3-6 Handler实现倒计时并优化内存

LemonNekoMK

2018-01-09 17:25:53

Activity代码如下:

package com.learn.chheese.app.networkles2;

import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class DownloadActivity extends AppCompatActivity {
    private static final String TAG = "DownloadActivity";
    private final String APK_URL="http://dl-cdn.coolapkmarket.com/down/apk_upload/2018/0105/E6898BE69CBAE6B798E5AE9D-0-o_1c32fuode1mh38t4jdf11uslav7-uid-97100.apk?_upt=56ebbe581515489839";
    private final String File_DIERCTORY=Environment.getExternalStorageDirectory().getPath()+"/DownloadDemo";
    private final String FILE_NAME="taobao.apk";
    private final int CODE_MESSAGE_DOWNLOADING=94750;
    private final int CODE_MESSAGE_ERROR_URL=94751;
    private final int CODE_MESSAGE_ERROR_IO=94752;
    private Button beginBtn;
    private ProgressBar downloadBar;
    private TextView statusText;
    private Handler mHandler;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_download);
        initView();
        initAction();
    }
    private void initView(){
        beginBtn=findViewById(R.id.btn_begin);
        downloadBar=findViewById(R.id.progress_download);
        statusText=findViewById(R.id.text_status);
    }
    private void initAction(){
        mHandler=new Handler(msg -> {
            switch (msg.what){
                case CODE_MESSAGE_DOWNLOADING:
                    downloadBar.setProgress(msg.arg1);
                    if (msg.arg1==100){
                        statusText.setText("下载完成");
                    }
                    break;
                case CODE_MESSAGE_ERROR_URL:
                    downloadBar.setSecondaryProgress(100);
                    statusText.setText("URL错误");
                    break;
                case CODE_MESSAGE_ERROR_IO:
                    downloadBar.setSecondaryProgress(100);
                    statusText.setText("IO错误");
                    break;
            }
            return false;
        });
        beginBtn.setOnClickListener(view->{
            new Thread(){
                @Override
                public void run() {
                    download(APK_URL);
                }
            }.start();
        });
    }
    private void download(String address){
        try {
            URL url=new URL(address);
            URLConnection conn=url.openConnection();
            InputStream in=conn.getInputStream();
            byte[] b=new byte[1024*1024*2];
            File file=new File(File_DIERCTORY);
            if (!file.exists()){
                file.mkdir();
            }
            file=new File(file,FILE_NAME);
            if (file.exists()){
                file.delete();
            }
            FileOutputStream fos=new FileOutputStream(file);
            int totalLength=conn.getContentLength();
            int downloadedLength= 0;
            int readLength;
            while ((readLength=in.read(b))!=-1){
                fos.write(b,0,readLength);
                downloadedLength+=readLength;
                Message msg=mHandler.obtainMessage();
                msg.what=CODE_MESSAGE_DOWNLOADING;
                double progress=downloadedLength*100.0/totalLength;
                Log.i(TAG, "progress: "+progress);
                msg.arg1=(int)progress;
                mHandler.sendMessage(msg);
            }
            fos.close();
        } catch (MalformedURLException e) {
            mHandler.sendEmptyMessage(CODE_MESSAGE_ERROR_URL);
            e.printStackTrace();
        } catch (IOException e) {
            mHandler.sendEmptyMessage(CODE_MESSAGE_ERROR_IO);
            e.printStackTrace();
        }
    }
}


写回答

1回答

irista23

2018-01-09

在Java中,非静态(匿名)内部类会默认隐性引用外部类对象,new Handler(){}方式就是一个匿名内部类。而实现Handler的callback接口方式则不是。



0
hemonNekoMK
h 谢谢
h018-01-09
共1条回复

0 学习 · 1613 问题

查看课程