调用MediaScannerConnection 发生内存泄露的解决方法
调用MediaScannerConnection发起扫描时经常会发生内存泄露,例如:
E ActivityThread: Activity FolderListActivity has leaked ServiceConnection android.media.MediaScannerConnection@ec2a697 that was originally bound here
从网上看到一种解决方法,就是把MediaScannerConnection单独放在一个类中,而不是直接在Activity中创建。
参考网址:
http://www.dreamincode.net/forums/topic/289977-service-connection-leak-error/
1.有问题的代码:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.createfile);
setupVariables();
checkState();
//Locates the SD Card's path to create a new directory
//If the directory does not exist, then it is created
path = new File(Environment.getExternalStorageDirectory(), dirName);
if(!path.exists()){
path.mkdirs();
}
//if you can read and write to storage
if (wEnable && rEnable) {
// Can Read and Write
confirm.setonclickListener(this);
// creates the library file
save.setonclickListener(this);
}
}
private void setupVariables() {
//The Variables are stored here
}
private void checkState() {
//Checks the state of the external storage. Not relevant to the problem
}
public void onclick(View v) {
switch (v.getId()) {
case R.id.bConfirm:
name = tv.getText().toString();
if (name.equals("")) {
error.setVisibility(View.VISIBLE);
}
else {
error.setVisibility(View.INVISIBLE);
save.setVisibility(View.VISIBLE);
}
break;
case R.id.bSave:
name = tv.getText().toString() + ".txt";
library = new File(path, name);
//This is where the problem occurs
MediaScannerConnection.scanFile(FileCreation.this, new String[]{library.toString()},
null, new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
// TODO Auto-generated method stub
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(FileCreation.this,
"Media scan completed",
Toast.LENGTH_SHORT).show();
}
});
}
});
finish();
break;
}
}
2.建议的代码:
You are creating a media scanner and running it and then calling finish(); while the service is still connected!
Create the following class :
import java.io.File;
import android.content.Context;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.net.Uri; public class SingleMediaScanner implements MediaScannerConnectionClient { public interface ScanListener{
public void onScanFinish();
} private MediaScannerConnection mMs;
private File mFile;
private ScanListener listener; public SingleMediaScanner(Context context, File f,ScanListener l) {
listener = l;
mFile = f;
mMs = new MediaScannerConnection(context, this);
mMs.connect();
} @Override
public void onMediaScannerConnected() {
mMs.scanFile(mFile.getAbsolutePath(), null);
} @Override
public void onScanCompleted(String path, Uri uri) {
mMs.disconnect();
listener.onScanFinish();
} }
Then in your code do the following:
new SingleMediaScanner(<context>,<File go here>,new ScanListener(){
public void onScanFinish()
{
finish();
Toast.makeText(FileCreation.this,"Media scan completed",Toast.LENGTH_SHORT).show();
});
3.修改后的代码:
package com.maclinCode; import java.io.File; import android.app.Activity;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.onclickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast; import com.maclinCode.SingleMediaScanner.ScanListener; public class FileCreation extends Activity implements onclickListener {
EditText tv;
TextView error;
Button save, confirm;
boolean wEnable, rEnable;
String name; File path = null;
File fileName = null;
File library = null;
private String state;
private static final String dirName = "GameLibrary";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.createfile);
setupVariables();
checkState(); //Locates the SD Card's path to create a new directory
//If the directory does not exist, then it is created
path = new File(Environment.getExternalStorageDirectory(), dirName);
if(!path.exists()){
path.mkdirs();
} //if you can read and write to storage
if (wEnable && rEnable) {
// Can Read and Write
confirm.setonclickListener(this);
// creates the library file
save.setonclickListener(this);
}
} private void setupVariables() {
confirm = (Button) findViewById(R.id.bConfirm);
save = (Button) findViewById(R.id.bSave);
tv = (EditText) findViewById(R.id.FileName); error = (TextView) findViewById(R.id.tvError);
state = Environment.getExternalStorageState();
wEnable = rEnable = false; } private void checkState() {
if (state.equals(Environment.MEDIA_MOUNTED)) {
// Can Read and Write to storage
wEnable = rEnable = true;
}
else{
Toast.makeText(this, "Cannot use External Storage", Toast.LENGTH_SHORT).show();
finish();
return;
}
} public void onclick(View v) {
switch (v.getId()) {
case R.id.bConfirm:
name = tv.getText().toString(); if (name.equals("")) {
error.setVisibility(View.VISIBLE);
}
else {
error.setVisibility(View.INVISIBLE);
save.setVisibility(View.VISIBLE);
}
break; case R.id.bSave:
name = tv.getText().toString() + ".txt";
library = new File(path, name); // MediaScannerConnection.scanFile(FileCreation.this, new String[]{library.toString()},
// null, new MediaScannerConnection.OnScanCompletedListener() {
// public void onScanCompleted(String path, Uri uri) {
// // TODO Auto-generated method stub
// runOnUiThread(new Runnable() {
// public void run() {
// Toast.makeText(FileCreation.this,
// "Media scan completed",
// Toast.LENGTH_SHORT).show();
// }
// });
// }
// });
// finish();
new SingleMediaScanner(FileCreation.this, library, new ScanListener(){
public void onScanFinish(){
finish();
Toast.makeText(FileCreation.this,
"Media scan completed",
Toast.LENGTH_SHORT).show();
}
});
break;
} } }
调用MediaScannerConnection 发生内存泄露的解决方法的更多相关文章
- 分享.net常见的内存泄露及解决方法
分享.net常见的内存泄露及解决方法 关于内存泄漏的问题,之前也为大家介绍过,比如:<C++中内存泄漏的检测方法介绍>,是关于C++内存泄漏的.今天为大家介绍的是关于.NET内存泄漏的问题 ...
- JS高程中的垃圾回收机制与常见内存泄露的解决方法
起因是因为想了解闭包的内存泄露机制,然后想起<js高级程序设计>中有关于垃圾回收机制的解析,之前没有很懂,过一年回头再看就懂了,写篇博客与大家分享一下. #内存的生命周期: 分配你所需要的 ...
- Android APP常见的5类内存泄露及解决方法
1.static变量引起的内存泄漏 因为static变量的生命周期是在类加载时开始 类卸载时结束,也就是说static变量是在程序进程死亡时才释放,如果在static变量中 引用了Activity 那 ...
- WPF不明内存泄露已解决,白头发也没了
原文:WPF不明内存泄露已解决,白头发也没了 在使用OpenExpressApp进行WPF应用开发过程中遇到多个内存泄漏的地方,在上一篇中求助了一个内存泄露问题[WPF不明内存泄露原因,头发都白了几根 ...
- Java常见的几种内存溢出及解决方法
Java常见的几种内存溢出及解决方法[情况一]:java.lang.OutOfMemoryError:Javaheapspace:这种是java堆内存不够,一个原因是真不够(如递归的层数太多等),另一 ...
- ASP.NET MVC 3 loginUrl自动变成Account/Login,并且发生404错误的解决方法
http://www.cnblogs.com/think8848/archive/2011/07/08/2100814.html ASP.NET MVC 3 loginUrl自动变成Account/L ...
- 《对“XXX::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们》的问题的解决方法
<对“XXX::Invoke”类型的已垃圾回收委托进行了回调.这可能会导致应用程序崩溃.损坏和数据丢失.向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们& ...
- 【javascript】内存泄露及其解决办法
1.内存泄露:一般由于开发者使用不当导致不用的内存没有被操作系统或者空闲内存池回收释放. 2.造成内存泄露的常见原因: 1) 意外的全局变量引起的内存泄露 2)闭包引起的内存泄露 闭包可以维持函数内局 ...
- PF不明内存泄露已解决,白头发也没了(转)
在使用OpenExpressApp进行WPF应用开发过程中遇到多个内存泄漏的地方,在上一篇中求助了一个内存泄露问题[WPF不明内存泄露原因,头发都白了几根],本篇与大家分享一下如何解决此问题的过程. ...
随机推荐
- SpringBoot学习之集成mybatis
一.spring boot集成Mybatis gradle配置: //gradle配置: compile("org.springframework.boot:spring-boot-star ...
- 使用JAXB解析xml文件(二)
前面一章简单演示了JAXB的用法,这个章节主要梳理一下JAXB常见的几个注解 1.@XmlRootElement 用于类级别的注解,对应xml的跟元素,常与 @XmlType 和 @XmlAccess ...
- day4 liaoxuefeng---函数
一.调用函数: 调用abs函数:取绝对值函数, >>> abs(100) 100 >>> abs(-20) 20 >>> abs(12.34) 1 ...
- SpringBoot中跨域问题
项目中经常会遇到浏览器跨域的问题,解决方式在启动类中配置 @Bean public FilterRegistrationBean corsFilter() { UrlBasedCorsConfigur ...
- rsync 系统用户/虚拟用户 备份web服务器数据及无交互定时推送备份
一.服务环境 (1),WEBserver(192.168.10.130) : BACKserver(192.168.10.129) (2),BACKserver服务器部署,安装所需软件,并启动 (3) ...
- spring基本原理
作者:王奕然链接:https://www.zhihu.com/question/21346206/answer/101789659来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...
- Hibernate 自动生产表
hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. 今天就来演示一下Hibernate最初级的 ...
- 借助Bodymovin播放svg动画
svg动画,截取工具有点不忍直视了~~~ 为了实现上面的svg动画,可以使用bodymovin插件,简单配置之后,就可以直接可以实现在 AE(可视化操作,不用码代码)上面导出 svg的json数据,在 ...
- C# get 、set、索引器
get 与 set C#类的属性有公有属性(public)和私有属性(private).如果直接将一个属性声明为public,则该类的任意实例可以随意获取或修改该属性的值,很不安全..NET Fram ...
- python的IDE(pycharm)安装以及简单配置
使用IDE的好处 界面更友好,看起来更舒服 智能提示功能很赞,大大提高开发效率 pycharm的安装过程 去pycharm官网下载安装包,请下载专业版,建议不要去网上下载汉化版 点击安装包一直下一步即 ...