我有一个基本的声音机器应用程序,并有很多帮助终于设法让声音播放,并在按下后退按钮时停止播放。现在我遇到的问题是,当我加载屏幕并播放声音时,按下后退按钮并尝试播放新声音,整个应用程序强制关闭。这是home.java和两个声音java类。
package com.androidsleepmachine.gamble;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
public class Home extends Activity implements View.OnClickListener {
Button Sleep1;
Button Sleep2;
Button Sleep3;
Button Relax1;
Button Relax2;
Button Relax3;
Button Well1;
Button Well2;
Button Well3;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home_layout);
TabHost tabHost = (TabHost) findViewById(R.id.tabHost);
tabHost.setup();
TabSpec spec1 = tabHost.newTabSpec("Sleep");
spec1.setContent(R.id.tab1);
spec1.setIndicator("Sleep",
getResources().getDrawable(R.drawable.sleep_icon));
TabSpec spec2 = tabHost.newTabSpec("Relaxation");
spec2.setIndicator("Relaxation",
getResources().getDrawable(R.drawable.zen_icon));
spec2.setContent(R.id.tab2);
TabSpec spec3 = tabHost.newTabSpec("Wellness");
spec3.setIndicator("Wellness",
getResources().getDrawable(R.drawable.brain_icon));
spec3.setContent(R.id.tab3);
tabHost.addTab(spec1);
tabHost.addTab(spec2);
tabHost.addTab(spec3);
Sleep1 = (Button) findViewById(R.id.button1);
Sleep1.setOnClickListener(this);
Sleep2 = (Button) findViewById(R.id.button2);
Sleep2.setOnClickListener(this);
Sleep3 = (Button) findViewById(R.id.button3);
Sleep3.setOnClickListener(this);
Relax1 = (Button) findViewById(R.id.button4);
Relax1.setOnClickListener(this);
Relax2 = (Button) findViewById(R.id.button5);
Relax2.setOnClickListener(this);
Relax3 = (Button) findViewById(R.id.button6);
Relax3.setOnClickListener(this);
Well1 = (Button) findViewById(R.id.button7);
Well1.setOnClickListener(this);
Well2 = (Button) findViewById(R.id.button8);
Well2.setOnClickListener(this);
Well3 = (Button) findViewById(R.id.button9);
Well3.setOnClickListener(this);
}
// Handle button callbacks
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
Intent a = new Intent(this, Ocean.class);
startActivity(a);
break;
case R.id.button2:
Intent i = new Intent(this, Ship.class);
startActivity(i);
break;
case R.id.button3:
Intent c = new Intent(this, OceanThunder.class);
startActivity(c);
break;
}
}
}
这是Ocean.Java
package com.androidsleepmachine.gamble;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
public class Ocean extends Activity implements View.OnClickListener {
public static final Integer[] TIME_IN_MINUTES = { 30, 45, 60, 180, 360 };
public MediaPlayer mediaPlayer;
public Handler handler = new Handler();
public Button button1;
public Spinner spinner1;
// Initialize the activity
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.ocean);
button1 = (Button) findViewById(R.id.btn1);
button1.setOnClickListener(this);
spinner1 = (Spinner) findViewById(R.id.spinner1);
ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(this,
android.R.layout.simple_spinner_item, TIME_IN_MINUTES);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner1.setAdapter(adapter);
}
protected void onStop()
{
if (this.mediaPlayer != null)
this.mediaPlayer.stop();
super.onStop();
}
// Play the sound and start the timer
private void playSound(int resourceId) {
// Cleanup any previous sound files
cleanup();
// Create a new media player instance and start it
mediaPlayer = MediaPlayer.create(this, resourceId);
mediaPlayer.start();
// Create the timer to stop the sound after x number of milliseconds
int selectedTime = TIME_IN_MINUTES[spinner1.getSelectedItemPosition()];
handler.postDelayed(runnable, selectedTime * 60 * 1000);
}
// Handle button callback
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn1:
playSound(R.raw.ocean_birds);
break;
}
}
// Stop the sound and cleanup the media player
public void cleanup() {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
// Cancel any previously running tasks
handler.removeCallbacks(runnable);
}
// Runnable task used by the handler to stop the sound
public Runnable runnable = new Runnable() {
public void run() {
cleanup();
}
};
和Ship.Java
package com.androidsleepmachine.gamble;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
public class Ship extends Activity implements View.OnClickListener {
public static final Integer[] TIME_IN_MINUTES = { 30, 45, 60, 180, 360 };
public MediaPlayer mediaPlayer;
public Handler handler = new Handler();
public Button button2;
public Spinner spinner2;
// Initialize the activity
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
setContentView(R.layout.ship);
button2 = (Button) findViewById(R.id.btn2);
button2.setOnClickListener(this);
spinner2 = (Spinner) findViewById(R.id.spinner2);
ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(this,
android.R.layout.simple_spinner_item, TIME_IN_MINUTES);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner2.setAdapter(adapter);
}
protected void onStop()
{
if (this.mediaPlayer != null)
this.mediaPlayer.stop();
super.onStop();
}
// Play the sound and start the timer
private void playSound(int resourceId) {
// Cleanup any previous sound files
cleanup();
// Create a new media player instance and start it
mediaPlayer = MediaPlayer.create(this, resourceId);
mediaPlayer.start();
// Create the timer to stop the sound after x number of milliseconds
int selectedTime = TIME_IN_MINUTES[spinner2.getSelectedItemPosition()];
handler.postDelayed(runnable, selectedTime * 60 * 1000);
}
// Handle button callback
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn2:
playSound(R.raw.ocean_ship);
break;
}
}
// Stop the sound and cleanup the media player
public void cleanup() {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
// Cancel any previously running tasks
handler.removeCallbacks(runnable);
}
// Runnable task used by the handler to stop the sound
public Runnable runnable = new Runnable() {
public void run() {
cleanup();
}
};
}
logcat的
09-19 14:58:17.533: D/dalvikvm(1675): GC_FOR_ALLOC freed 5637K, 22% free 40867K/51783K, paused 35ms, total 37ms
09-19 14:58:17.533: I/dalvikvm-heap(1675): Grow heap (frag case) to 44.671MB for 4915212-byte allocation
09-19 14:58:17.554: D/dalvikvm(1675): GC_CONCURRENT freed 2K, 12% free 45664K/51783K, paused 16ms+1ms, total 21ms
09-19 14:58:17.688: D/dalvikvm(1675): GC_FOR_ALLOC freed 0K, 12% free 45664K/51783K, paused 33ms, total 33ms
09-19 14:58:17.693: I/dalvikvm-heap(1675): Grow heap (frag case) to 53.004MB for 8739852-byte allocation
09-19 14:58:17.713: D/dalvikvm(1675): GC_CONCURRENT freed 0K, 11% free 54199K/60359K, paused 13ms+2ms, total 20ms
09-19 14:59:00.994: D/dalvikvm(1675): GC_FOR_ALLOC freed 4816K, 19% free 49464K/60359K, paused 35ms, total 40ms
09-19 14:59:00.994: I/dalvikvm-heap(1675): Grow heap (frag case) to 52.286MB for 4096012-byte allocation
09-19 14:59:01.014: D/dalvikvm(1675): GC_CONCURRENT freed 8K, 12% free 53455K/60359K, paused 13ms+1ms, total 21ms
09-19 14:59:01.154: D/dalvikvm(1675): GC_FOR_ALLOC freed <1K, 12% free 53455K/60359K, paused 5ms, total 5ms
09-19 14:59:01.154: I/dalvikvm-heap(1675): Forcing collection of SoftReferences for 7285488-byte allocation
09-19 14:59:01.174: D/dalvikvm(1675): GC_BEFORE_OOM freed 9K, 12% free 53446K/60359K, paused 19ms, total 20ms
09-19 14:59:01.174: E/dalvikvm-heap(1675): Out of memory on a 7285488-byte allocation.
09-19 14:59:01.174: I/dalvikvm(1675): "main" prio=5 tid=1 RUNNABLE
09-19 14:59:01.174: I/dalvikvm(1675): | group="main" sCount=0 dsCount=0 obj=0xb2e454b0 self=0xb9b594e0
09-19 14:59:01.174: I/dalvikvm(1675): | sysTid=1675 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=-1208622016
09-19 14:59:01.174: I/dalvikvm(1675): | schedstat=( 0 0 0 ) utm=158 stm=17 core=0
09-19 14:59:01.184: I/dalvikvm(1675): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
09-19 14:59:01.184: I/dalvikvm(1675): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:500)
09-19 14:59:01.184: I/dalvikvm(1675): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:353)
09-19 14:59:01.184: I/dalvikvm(1675): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:781)
09-19 14:59:01.184: I/dalvikvm(1675): at android.content.res.Resources.loadDrawable(Resources.java:1930)
09-19 14:59:01.184: I/dalvikvm(1675): at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
09-19 14:59:01.184: I/dalvikvm(1675): at android.view.View.<init>(View.java:3336)
09-19 14:59:01.184: I/dalvikvm(1675): at android.view.View.<init>(View.java:3273)
09-19 14:59:01.184: I/dalvikvm(1675): at android.view.ViewGroup.<init>(ViewGroup.java:421)
09-19 14:59:01.184: I/dalvikvm(1675): at android.widget.RelativeLayout.<init>(RelativeLayout.java:184)
09-19 14:59:01.184: I/dalvikvm(1675): at java.lang.reflect.Constructor.constructNative(Native Method)
09-19 14:59:01.184: I/dalvikvm(1675): at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
09-19 14:59:01.184: I/dalvikvm(1675): at android.view.LayoutInflater.createView(LayoutInflater.java:587)
09-19 14:59:01.184: I/dalvikvm(1675): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
09-19 14:59:01.184: I/dalvikvm(1675): at android.view.LayoutInflater.onCreateView(LayoutInflater.java:660)
09-19 14:59:01.184: I/dalvikvm(1675): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:685)
09-19 14:59:01.184: I/dalvikvm(1675): at android.view.LayoutInflater.inflate(LayoutInflater.java:466)
09-19 14:59:01.184: I/dalvikvm(1675): at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
09-19 14:59:01.184: I/dalvikvm(1675): at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
09-19 14:59:01.184: I/dalvikvm(1675): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:256)
09-19 14:59:01.184: I/dalvikvm(1675): at android.app.Activity.setContentView(Activity.java:1867)
09-19 14:59:01.184: I/dalvikvm(1675): at com.androidsleepmachine.gamble.Ocean.onCreate(Ocean.java:23)
09-19 14:59:01.184: I/dalvikvm(1675): at android.app.Activity.performCreate(Activity.java:5008)
09-19 14:59:01.184: I/dalvikvm(1675): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
09-19 14:59:01.184: I/dalvikvm(1675): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
09-19 14:59:01.184: I/dalvikvm(1675): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
09-19 14:59:01.184: I/dalvikvm(1675): at android.app.ActivityThread.access$600(ActivityThread.java:130)
09-19 14:59:01.184: I/dalvikvm(1675): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
09-19 14:59:01.184: I/dalvikvm(1675): at android.os.Handler.dispatchMessage(Handler.java:99)
09-19 14:59:01.184: I/dalvikvm(1675): at android.os.Looper.loop(Looper.java:137)
09-19 14:59:01.184: I/dalvikvm(1675): at android.app.ActivityThread.main(ActivityThread.java:4745)
09-19 14:59:01.184: I/dalvikvm(1675): at java.lang.reflect.Method.invokeNative(Native Method)
09-19 14:59:01.184: I/dalvikvm(1675): at java.lang.reflect.Method.invoke(Method.java:511)
09-19 14:59:01.184: I/dalvikvm(1675): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
09-19 14:59:01.184: I/dalvikvm(1675): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
09-19 14:59:01.184: I/dalvikvm(1675): at dalvik.system.NativeStart.main(Native Method)
09-19 14:59:01.204: A/libc(1675): Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 1675 (pmachine.gamble)
马纳费斯特
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidsleepmachine.gamble"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.androidsleepmachine.gamble.Home"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.androidsleepmachine.gamble.Ship" />
<activity android:name="com.androidsleepmachine.gamble.OceanThunder" />
<activity android:name="com.androidsleepmachine.gamble.Ocean" />
</application>
</manifest>
答案 0 :(得分:0)
检查你是否已经更新了你的“清单”,这是非常常见的问题。我们的思想忙于代码,我们经常忘记更新清单。
答案 1 :(得分:0)
问题可能就在这里
protected void onStop()
{
if (this.mediaPlayer != null)
this.mediaPlayer.stop();
super.onStop();
}
我相信你应该在这里打mediaPlayer.release()
。我此时对MediaPlayer
的体验有限,但我认为调用stop()
是不够的。您需要释放资源。如果这不起作用,那么你需要发布完整的logcat,因为如果它崩溃了,那么你的logcat会比你提供的更多。
这在onPause()
中也可能更安全。
从评论中更新
protected void onStop()
{
if (this.mediaPlayer != null)
this.mediaPlayer.stop();
mediaPlayer.release(); // release your resources
super.onStop();
}
但正如我所说,这可能比onPause()
而不是onStop()
更安全。这将适用于用户按下后退按钮但不会在其他内容进入前台时。
答案 2 :(得分:0)
代码魔术是对的。您需要致电发布。
protected void onStop(){
if (this.mediaPlayer != null){
super.onStop();
this.mediaPlayer.stop();
this.mediaPlayer.release();
}
应该这样做。