调用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 发生内存泄露的解决方法的更多相关文章

  1. 分享.net常见的内存泄露及解决方法

    分享.net常见的内存泄露及解决方法 关于内存泄漏的问题,之前也为大家介绍过,比如:<C++中内存泄漏的检测方法介绍>,是关于C++内存泄漏的.今天为大家介绍的是关于.NET内存泄漏的问题 ...

  2. JS高程中的垃圾回收机制与常见内存泄露的解决方法

    起因是因为想了解闭包的内存泄露机制,然后想起<js高级程序设计>中有关于垃圾回收机制的解析,之前没有很懂,过一年回头再看就懂了,写篇博客与大家分享一下. #内存的生命周期: 分配你所需要的 ...

  3. Android APP常见的5类内存泄露及解决方法

    1.static变量引起的内存泄漏 因为static变量的生命周期是在类加载时开始 类卸载时结束,也就是说static变量是在程序进程死亡时才释放,如果在static变量中 引用了Activity 那 ...

  4. WPF不明内存泄露已解决,白头发也没了

    原文:WPF不明内存泄露已解决,白头发也没了 在使用OpenExpressApp进行WPF应用开发过程中遇到多个内存泄漏的地方,在上一篇中求助了一个内存泄露问题[WPF不明内存泄露原因,头发都白了几根 ...

  5. Java常见的几种内存溢出及解决方法

    Java常见的几种内存溢出及解决方法[情况一]:java.lang.OutOfMemoryError:Javaheapspace:这种是java堆内存不够,一个原因是真不够(如递归的层数太多等),另一 ...

  6. 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 ...

  7. 《对“XXX::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们》的问题的解决方法

    <对“XXX::Invoke”类型的已垃圾回收委托进行了回调.这可能会导致应用程序崩溃.损坏和数据丢失.向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们& ...

  8. 【javascript】内存泄露及其解决办法

    1.内存泄露:一般由于开发者使用不当导致不用的内存没有被操作系统或者空闲内存池回收释放. 2.造成内存泄露的常见原因: 1) 意外的全局变量引起的内存泄露 2)闭包引起的内存泄露 闭包可以维持函数内局 ...

  9. PF不明内存泄露已解决,白头发也没了(转)

    在使用OpenExpressApp进行WPF应用开发过程中遇到多个内存泄漏的地方,在上一篇中求助了一个内存泄露问题[WPF不明内存泄露原因,头发都白了几根],本篇与大家分享一下如何解决此问题的过程. ...

随机推荐

  1. 【SDOI2009】学校食堂

    Description 小F的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用 ...

  2. bzoj 1046: [HAOI2007]上升序列

    Description 对于一个给定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},满足(x1 < x2 < … < xm)且( ax1 < ...

  3. hdu 1133 Buy the Ticket(Catalan)

    Buy the Ticket Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T ...

  4. 【TensorFlow 官网 可以直接访问】让中国开发者更容易地使用TensorFlow打造人工智能应用

    人工智能的神奇之处,在于它能被应用在医疗保健.交通运输和环境保护等方方面面,为复杂的社会问题探寻解决方案.如今,在人工智能的协助下,人们得以探索全新的研究领域,开发创新的产品,让数以百万计的用户从中获 ...

  5. ES6数组新增的几个方法

    关于数组中forEach() .map().filter().reduce().some().every()的总结 1.forEach() var arr = [1,2,3,4]; arr.forEa ...

  6. Dapper.Contrib拓展及数据库生成实体

    1.关于Dapper.Contrib Dapper.Contrib是Dapper的一个拓展类库,Dapper是一个轻量级ORM框架,这个不了解的请自行收集资料,本文主要讲讲,数据库生成实体,并通过实体 ...

  7. 详解linux进程间通信-管道 popen函数 dup2函数

    前言:进程之间交换信息的唯一方法是经由f o r k或e x e c传送打开文件,或通过文件系统.本章将说明进程之间相互通信的其他技术-I P C(InterProcess Communication ...

  8. javascript templating

    JavaScript Micro-Templating I’ve had a little utility that I’ve been kicking around for some time no ...

  9. SUSE10的虚拟机安装以及ORACLE 11g的安装

    SUSE10虚拟机安装与ORACLE安装 作者:张欣橙 本文所需要的所有参数均位于文末附录中 一.SUSE10虚拟机的安装与创建 新建虚拟机安装 选择下一步 选择下一步 选择下一步 选择下一步 选择下 ...

  10. solr服务器搭建

    百度百科定义:Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口.用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引:也可以通过Ht ...