Frage

I have a basic sound machine app and with lots of help have finally managed to get the sounds to play and stop playing upon hitting the back button. Now the issue I am having is when I load a screen and play a sound, hit the back button and try to play a new sound the whole app force closes. here is the home.java, and two sound java classes.

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;
    }
}
}

Here is the 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();
    }
};

and the 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)

Manafest

<?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>
War es hilfreich?

Lösung

The problem is probably here

    protected void onStop()
  {
    if (this.mediaPlayer != null)
      this.mediaPlayer.stop();
      super.onStop();
  }

I believe you should be calling mediaPlayer.release() here. My experience with MediaPlayer at this point is limited but I believe that calling stop() is not enough. You need to release the resources. If this doesn't work then you need to post the full logcat because if it crashed then there is more to your logcat than you have provided.

This may also be safer to be done in onPause().

Update from comment

 protected void onStop()
  {
    if (this.mediaPlayer != null)
      this.mediaPlayer.stop();
      mediaPlayer.release();   // release your resources
      super.onStop();
  }

but as I said, this may be safer to do in onPause() instead of onStop(). This will work for when the user presses the back button but not if something else comes into the foreground.

Andere Tipps

Check if you have up you updated your "manifest", this is very common problem. Our mind is so busy with the code that we often forget updating the manifest.

code Magic is right. Your need to call release.

protected void onStop(){
    if (this.mediaPlayer != null){
        super.onStop();
        this.mediaPlayer.stop();
        this.mediaPlayer.release();  
    }

That should do it.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top