调用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. 【Remmarguts' Date】

    一道来自POJ2449的题,它融合了单源点最短路算法.启发式搜索,让我们对“启发式”有更深的理解和体会.Wow! ·英文题,述大意:       读入n,m(n<=1000,m<=1000 ...

  2. bzoj1233[Usaco2009Open]干草堆tower 单调队列优化dp

    1233: [Usaco2009Open]干草堆tower Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 983  Solved: 464[Submi ...

  3. Python virtualenv 使用总结篇

    一.virtualenv的安装 1.使用pip全局安装virtualenv,建议使用pip 1.3或更高版本,在1.3之前,pip没有通过SSL从PYPI下载. $ [sudo] pip instal ...

  4. jquery 中toggle的2种用法

    一.在元素的click事件中绑定两个或两个以上的函数  toggle不像bind需要在后面添加"click"来绑定click触发事件,toggle本身就是click触发的(而且只能 ...

  5. C语言第三次程序设计作业

    (一)改错题 计算f(x)的值:输入实数x,计算并输出下列分段函数f(x)的值,输出时保留1位小数. 1)源程序(有错误的程序) #include <stdio.h> int main(v ...

  6. Jenkins的关闭、重启

    以前一直用从cmd进入jenkins的安装目录,执行jenkins stop/start,但是新的jenkins有更加方便功能 关闭jenkins服务 只需要在访问jenkins服务器的网址url地址 ...

  7. webpack require.ensure 按需加载

    使用 vue-cli构建的项目,在 默认情况下 ,会将所有的js代码打包为一个整体比如index.js.当使用存在多个路由代码的时候,index.js可能会超大,影响加载速度. 这个每个路由页面除了i ...

  8. 函数的属性和方法之call、apply 及bind

    一.前言 ECMAScript中的函数是对象,因此函数也有属性和方法.每个函数都包含两个属性:length和prototype.每个函数也包含两个非继承来的方法:apply()和call(),还有一些 ...

  9. 628. Maximum Product of Three Numbers

    Given an integer array, find three numbers whose product is maximum and output the maximum product. ...

  10. 通过内核修改centos密码

    在开机启动的时候按键盘上的"E"键会进入如下界面. 选择相应的内核,再次按"E",出现下图,选择第二项,再次按"E"键 经过第二步,这个画面 ...