Android/Java: как ссылаться из класса на MainActivity.java

Извините за вопрос, вероятно, на него ответят в течение нескольких минут. Я новичок в разработке приложений для Android и искал ответ около 2 часов, но не нашел решения.

Итак, это моя проблема: я создал MainActivity с очень простым макетом, только один ToggleButton для запуска/остановки звука. Я заставил его работать с вызовом MediaPlayer из класса MainActivity. Теперь я хочу поместить MediaPlayer-Handling в отдельный класс, чтобы его можно было вызывать и из виджета. При поднятии Toast или вызове MediaPlayer-Method мне нужно обратиться к MainActivity, которая была (в самой MainActivity) «этой». Но я не знаю, как обратиться к экземпляру MainActivity.

Код выглядит следующим образом:

package com.heavyloadreverse;

//import java.io.IOException;

import android.app.Activity;
//import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
//import android.widget.Toast;
import android.widget.ToggleButton;

public class MainActivity extends Activity {

    //private MediaPlayer mp;
    private Sound snd;
    private ToggleButton btn;   

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btn = (ToggleButton) findViewById(R.id.btn_OnOff);
        snd = new Sound();
        snd.mp_create(MainActivity.this);
    }

    public void onToggleClicked(View v) {       
        // Perform action on clicks
        if (((ToggleButton) v).isChecked()) {            
            snd.mp_start();
        } else {            
            snd.mp_stop();
        }
    }

    /*********************************************************************************
    public void mp_create() {
        mp = MediaPlayer.create(this, R.raw.truckreverse);
    }

    public void mp_start () {
        Toast.makeText(this, R.string.start, Toast.LENGTH_SHORT).show();
        // start the sound  
        mp.setLooping(true);
        mp.start();
    }

    public void mp_stop () {
        Toast.makeText(this, R.string.stop, Toast.LENGTH_SHORT).show();
        // stop the sound
        mp.stop();
        try {
            mp.prepare();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void mp_init() {
        btn.setChecked(false); 
    }
    **********************************************************************************/

    public void btn_init() {
        btn.setChecked(false); 
    }   

    @Override
    public void onStart() {
        super.onStart();
    }

    @Override
    public void onRestart() {
        super.onRestart();      
        btn_init();     
    }

    @Override
    public void onResume() {
        super.onResume();
        btn_init();
    }

    @Override
    public void onPause() {
        super.onPause();
        snd.mp_stop();
    }

    @Override
    public void onStop() {
        super.onStop();
        snd.mp_stop();
    }

    @Override
    public void onDestroy() {
        super.onDestroy(); 
        snd.mp_stop();
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);      
    }

}

Класс для MediaPlayer-Handling:

package com.heavyloadreverse;

import java.io.IOException;

import android.app.Application;
import android.media.MediaPlayer;
import android.widget.Toast;
import com.heavyloadreverse.R;

public class Sound extends Application {

    private MediaPlayer mp; 

    public void mp_create (MainActivity main) {
        Toast.makeText(main.this, "test", Toast.LENGTH_SHORT).show();
        mp = new MediaPlayer();
        try {
            mp = MediaPlayer.create(this, R.raw.truckreverse); 
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (RuntimeException e) {
            e.printStackTrace();
        }       
    }

    public void mp_start () {
        Toast.makeText(MainActivity.this, R.string.start, Toast.LENGTH_SHORT).show();
        // start the sound  
        try {
            mp.setLooping(true);
            mp.start();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (RuntimeException e) {
            e.printStackTrace();
        }       
    }

    public void mp_stop () {
        //Toast.makeText(this, R.string.stop, Toast.LENGTH_SHORT).show();       
        try {
            // stop the sound
            mp.stop();
            mp.prepare();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
    }

}

Toast.makeText(this, "test", Toast.LENGTH_SHORT).show();

--> вызывает ошибку времени выполнения при выполнении:

--> 03-12 20:23:18.412: E/AndroidRuntime(862): java.lang.RuntimeException: невозможно запустить действие ComponentInfo{com.heavyloadreverse/com.heavyloadreverse.MainActivity}: java.lang.NullPointerException

Toast.makeText(main.this, "test", Toast.LENGTH_SHORT).show();

--> ошибка в коде:

--> *Несколько маркеров в этой строке - main не может быть разрешен к типу - Line breakpoint:Sound [строка: 15] - mp_create(MainActivity)*

Toast.makeText(MainActivity.this, "test", Toast.LENGTH_SHORT).show();

--> ошибка в коде:

--> Ни один экземпляр типа MainActivity не доступен в области действия

Что мне нужно сделать, чтобы Toast- и MediaPlayer-Calls в «Sound.java» работали?

Заранее большое спасибо.

Свен


person LiNalasNORDIC    schedule 12.03.2012    source источник


Ответы (3)


Вариант 1. Добавьте «Контекст» в качестве параметра «Звук».

public class Sound{
    private Context mContext;
    Sound(Context context){
        mContext = context;
    }

    ...
    Toast.makeText(mContext, text, length).show();
    ...
}

Когда вы создаете Sound из активности, вы делаете это так же, как new Sound(this);

Вариант 2

Определите интерфейс в Sound для обеспечения обратных вызовов

public class Sound {
    interface OnSoundListener{
        public void onSoundStarted();
        public void onSoundStopped();
    }
}

И ваша основная деятельность будет выглядеть так

public class MainActivity implements Sound.OnSoundListener{
    @Override
    public void onSoundStarted(){
        //your toast here
    }
}

Лично я предпочитаю второй, так вы можете отделить логику от пользовательского интерфейса.

person Axxiss    schedule 07.08.2013

Не уверен, что это работа, только идея.

Прежде всего, расширьте свой класс Sound из вашей MainActivity.

public class Sound extends MainActivity {

во-вторых, это код, который я использую для работы Toast:

Toast.makeText(MainActivity.this,"Your Text Here",Toast.LENGTH_LONG).show();
person LuizAurio    schedule 12.03.2012
comment
Кажется, я пробовал это вчера. Тоже столкнулся с какой-то ошибкой, но я попробую, когда буду дома сегодня вечером. Спасибо.. - person LiNalasNORDIC; 13.03.2012
comment
Это действительно плохая идея, так как вы вводите новую активность (со всеми необходимыми объектами) в систему, требующую больше ресурсов, чем требуется. - person Axxiss; 07.08.2013

Для Toast это то, что вам нужно сделать:

Toast toast=Toast.makeText(this, "Hello toast", 2000);

     toast.show();

Ознакомьтесь с этим руководством , если оно поможет .

person kosa    schedule 12.03.2012
comment
Это работает, если я вызываю Toast из MainActivity. Если я вызову его из класса Sound, я получу ошибку времени выполнения, как упоминалось выше. Ссылка на это является проблемой. - person LiNalasNORDIC; 13.03.2012
comment
Я вижу, вы можете попробовать getApplicationContext() вместо этого. Я не перед компьютером, чтобы проверить это, но вы можете попробовать. - person kosa; 13.03.2012
comment
Я собираюсь дать ему шанс, когда я буду дома сегодня вечером. Спасибо. - person LiNalasNORDIC; 13.03.2012