如果用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回答
在Java中,非静态(匿名)内部类会默认隐性引用外部类对象,new Handler(){}方式就是一个匿名内部类。而实现Handler的callback接口方式则不是。
相似问题