zoukankan      html  css  js  c++  java
  • 调用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;
    		}
    
    	}
    
    }
    



  • 相关阅读:
    字符串函数使用与 Culture
    学习 Monitor使用
    Extjs的ajax实现
    linux下tomcat的安装及部署
    使用jquery插件实现打印指定区域功能
    hibernate的各种保存方式的区别 (save,persist,update,saveOrUpdte,merge,flush,lock)等
    html 树形菜单
    Ext4 修复对话框按钮翻译
    spring aop expression简单说明
    tomcat内存溢出的解决方法(java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError:)
  • 原文地址:https://www.cnblogs.com/muyuge/p/6152412.html
Copyright © 2011-2022 走看看