Android - Activity 泄露了 IntentReceiver
Posted
技术标签:
【中文标题】Android - Activity 泄露了 IntentReceiver【英文标题】:Android - Activity has leaked IntentReceiver 【发布时间】:2012-05-22 22:19:02 【问题描述】:我正在编写非常简单的应用程序。它工作正常,但是当我按下后退键时它崩溃(Activity 泄露了最初在此处注册的 IntentReceiver)。这个应用程序应该在后台运行。怎么做才合适?
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
public class Bateria extends Activity implements OnClickListener, OnSeekBarChangeListener
ProgressBar pbBatteryLevel;
TextView tvBatteryLevel;
TextView tvLeft;
RadioButton rbPercent;
RadioButton rbTime;
SeekBar sbSetLeft;
boolean percent; // true - percent, false - time
boolean informed;
int progress;
int MAX_TIME;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
PowerManager pM = (PowerManager) getSystemService(Context.POWER_SERVICE);
WakeLock wL = pM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "whatever");
long HOURS24 = 86400000;
super.onCreate(savedInstanceState);
wL.acquire(HOURS24);
setContentView(R.layout.main);
initialize();
@Override
protected void onResume()
// TODO Auto-generated method stub
super.onResume();
registerReceiver(batteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
private void initialize()
// TODO Auto-generated method stub
SharedPreferences preferences = getSharedPreferences("SP_BATTERY", 0);
percent = preferences.getBoolean("percent", true);
progress = preferences.getInt("progress", 0);
informed = false;
MAX_TIME = 72*60;
pbBatteryLevel = (ProgressBar) findViewById(R.id.pbBatteryLevel);
tvBatteryLevel = (TextView) findViewById(R.id.tvBatteryLevel);
tvBatteryLevel.setTextSize(20);
tvLeft = (TextView) findViewById(R.id.tvLeft);
if(percent)
tvLeft.setText(String.valueOf(progress) + " %");
else
int minutes = MAX_TIME*progress/100;
int hours = minutes / 60;
minutes -= hours*60;
tvLeft.setText(String.valueOf(hours) + "h " + String.valueOf(minutes) + "min");
rbPercent = (RadioButton) findViewById(R.id.rbPercent);
rbPercent.setOnClickListener(this);
rbPercent.setChecked(percent);
rbTime = (RadioButton) findViewById(R.id.rbTime);
rbTime.setOnClickListener(this);
rbTime.setChecked(!percent);
sbSetLeft = (SeekBar) findViewById(R.id.sbSetPercent);
sbSetLeft.setOnSeekBarChangeListener(this);
sbSetLeft.setProgress(progress);
registerReceiver(batteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
private BroadcastReceiver batteryInfoReceiver = new BroadcastReceiver()
@Override
public void onReceive(Context c, Intent i)
int level = i.getIntExtra("level", 0);
int voltage = i.getIntExtra("voltage", 0);
int temperature = i.getIntExtra("temperature", 0);
pbBatteryLevel.setProgress(level);
tvBatteryLevel.setText("Battery Level: " + Integer.toString(level)
+ "%" + "\n" + voltage + " mV " + temperature + " C");
if(level < progress && !informed)
//////////
Toast.makeText(getApplicationContext(), "BATTERY", Toast.LENGTH_LONG).show();
MediaPlayer mp = MediaPlayer.create(Bateria.this, R.raw.explosion);
mp.start();
//////////
informed = true;
else if(level >= progress)
informed = false;
;
public void onClick(View v)
// TODO Auto-generated method stub
switch(v.getId())
case(R.id.rbPercent):
percent = true;
tvLeft.setText(String.valueOf(progress) + " %");
break;
case(R.id.rbTime):
percent = false;
int minutes = MAX_TIME*progress/100;
int hours = minutes / 60;
minutes -= hours*60;
tvLeft.setText(String.valueOf(hours) + "h " + String.valueOf(minutes) + "min");
break;
SharedPreferences preferences = getSharedPreferences("SP_BATTERY", 0);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("percent", percent);
editor.commit();
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser)
// TODO Auto-generated method stub
if(percent)
tvLeft.setText(String.valueOf(progress) + " %");
else
int minutes = MAX_TIME*progress/100;
int hours = minutes / 60;
minutes -= hours*60;
tvLeft.setText(String.valueOf(hours) + "h " + String.valueOf(minutes) + "min");
this.progress = progress;
SharedPreferences preferences = getSharedPreferences("SP_BATTERY", 0);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("progress", progress);
editor.commit();
informed = false;
public void onStartTrackingTouch(SeekBar seekBar)
// TODO Auto-generated method stub
public void onStopTrackingTouch(SeekBar seekBar)
// TODO Auto-generated method stub
@Override
public boolean onCreateOptionsMenu(Menu menu)
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu);
MenuInflater blowUp = getMenuInflater();
blowUp.inflate(R.menu.menu, menu);
return true;
@Override
public boolean onOptionsItemSelected(MenuItem item)
// TODO Auto-generated method stub
System.exit(0);
return false;
【问题讨论】:
【参考方案1】:首先,您需要根据需要取消注册已注册的 BroadcastReceiver。更多信息请看这里:http://developer.android.com/reference/android/content/BroadcastReceiver.html
更重要的是,你不能仅仅通过开发一个 Activity 来开发一个在后台运行的应用程序。您需要为此开发服务。检查此链接以获取有关如何执行此操作的说明以及 API 文档:http://developer.android.com/reference/android/app/Service.html
【讨论】:
以上是关于Android - Activity 泄露了 IntentReceiver的主要内容,如果未能解决你的问题,请参考以下文章
Activity 泄露了原本绑定在这里的 ServiceConnection com.google.android.youtube.player
Activity 泄露了原本绑定在这里的 ServiceConnection com.google.android.youtube.player
Activity 泄露了 IntentReceiver - LollipopBrowserAccessibilityManager