调用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. 树链剖分模板(BZOJ3083)

    实现了路径修改,子树查询,及换根. 换根其实很简单,分三种情况讨论,画画图就明白了. #include <cstdio> #include <algorithm> using ...

  2. OCP 认证考试报名费技巧题库051052053解析合格线

    本人于2017年4月22日通过参加OCP考试,第一次参加,一天之内考了三门,三门一次性通过,052 - 95% ,053 - 86% ,051 - 100% 一.关于考试考试报名费: 052:158$ ...

  3. AspNetCoreApi 跨域处理

    AspNetCoreApi 跨域处理 如果咱们有处理过MV5 跨域问题这个问题也不大. (1)为什么会出现跨域问题:  浏览器安全限制了前端脚本跨站点的访问资源,所以在调用WebApi 接口时不能成功 ...

  4. java随机生成字符串和校验

    首先定义字符串 String a = "0123456789"; // 数字 String b = "abcdefghijklmnopqrstuvwxyz"; ...

  5. unittest测试框架详谈及实操(二)

    类级别的setUp()方法与tearDown()方法 在实操(一)的例子中,通过setUp()方法为每个测试方法都创建了一个Chrome实例,并且在每个测试方法执行结束后要关闭实例.是不是觉得有个多余 ...

  6. Windows转Linux总结(附带常用Linux命令-LinuxMint)

    这是我在Linux系统下写的第一篇博客,花了一周的时间从Windows系统转到Linux并且可以完成日常操作,能在Linux系统下完成开发,运用各种开发工具,写各种语言小程序和JavaEE. 经过这一 ...

  7. gcc创建静态库和共享库

    静态库和动态(共享)库静态库:编译程序在编译使用库提供的功能代码的程序时将代码复制到该程序然后编译成可执行程序,这种库成为静态库共享库:共享库比静态库的处理方式更加灵活,因而其产生的可执行文件更小,其 ...

  8. ERP中的地区管理

    地区管理 地区管理主要实现地区数据的添加.编辑.查看.启用.禁用等功能,另外还包含地区选择控件封装. 业务功能点: 地区数据查看:地区列表树状展现,列表增加省.市.区.县.乡图标. 地区选择控件:选择 ...

  9. Django网站制作

    创建mysite目录 django-admin.py startproject mysite这个命令作用是:这将创建在当前目录创建一个mysite目录 前提是从命令行上cd到你想储存你代码的目录,然后 ...

  10. Redis之(一)初识Redis

    1.Redis概述 我们知道,内存是电脑主板上的存储部件,用于存储当前正在使用的数据和程序,CPU可以与内存直接沟通,所以访问速速非常高:而外存数据必须加载到内存以后程序才能使用.如果把CPU当做一个 ...