java - 线程、MediaPlayer、ProgressDialog 和上下文问题

标签 java android android-mediaplayer android-context

我已经尝试并完成了我在互联网和 stackoverflow 上阅读的所有内容来解决我的问题,但到目前为止还没有成功。我想做的基本上是单击按钮并在 MediaPlayer 缓冲来自互联网的流时显示 ProgressDialog。我遇到了许多类型的上下文错误(NullPointerException)和线程问题。以下是有关代码的一些详细信息:

  1. 该按钮是一个切换按钮,其背景图像基于事件(打开、关闭、未连接时显示不同的图像按钮);
  2. 函数 prepareStream() 应该在线程中运行,并在加载流后关闭 ProgressDialog。它正在调用 BBC 广播电台的 http 流;
  3. 我猜问题出在上下文上...我在代码上放置了一些 Log.d 标签来检查问题发生的位置,O 发现问题出在 mediaPlayer.start() 方法。

他走了小男孩:

package com.android.iFocus;


import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.ToggleButton;

import com.insightoverflow.iFocus.R;

public class iFocusActivity extends Activity implements OnClickListener {


    //Declare Controls
    public int count = 0;
    public int x = 1;
    public MediaPlayer mediaPlayer = null;
    ToggleButton toggleRain = null;
    Button buttonAbout = null;
    Button buttonMethod = null;
    Button buttonLink = null;
    public ProgressDialog progressDialog;
    public static final String TAG = "getFocused";



    public boolean isOnline() {
        //Check if internet is connected
        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null;

    }

    public void prepareStream(final Context context){
        if(isOnline()){
            // init player


            new Thread() 
            {
                public void run() 
                {

                    try {

                        sleep(1500);
                        //progressDialog.show();
                        mediaPlayer = MediaPlayer.create(context, Uri.parse("http://vprbbc.streamguys.net:80/vprbbc24.mp3"), null);
                        x=2;

                    } catch (Exception e){
                    x=3;
                }

                //dismiss the progressdialog   
                progressDialog.dismiss();
                }
            }.start();


        } else {
            x=3;
        }
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        // load layout
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


        // load controls
        toggleRain = (ToggleButton)findViewById(R.id.toggleRain);
        buttonAbout = (Button)findViewById(R.id.buttonAbout);
        buttonMethod = (Button)findViewById(R.id.buttonMethod);
        buttonLink = (Button)findViewById(R.id.buttonLink);


        //Define Listeners (click event handler)
        toggleRain.setOnClickListener(this);
        buttonAbout.setOnClickListener(this);
        buttonMethod.setOnClickListener(this);
        buttonLink.setOnClickListener(this);


        // init state for player
        count = 0;

        //Context APP
        //Context appContext = this.getApplicationContext();

        if (!isOnline()){
            toggleRain.setBackgroundDrawable(getResources().getDrawable(R.drawable.notconnectedbutton));
            x=3;
        }

    }


    public void onClick(View v) {


        if( toggleRain.getId() == ((Button)v).getId() ){

            //meanwhile device is offline, do this
            do {
                toggleRain.setBackgroundDrawable(getResources().getDrawable(R.drawable.notconnectedbutton));
                try{
                      Thread.currentThread();
                    //do what you want to do before sleeping
                      Thread.sleep(1000);//sleep for 1000 ms
                      //do what you want to do after sleeptig
                } catch(Exception ie){}

                continue;
            }while (!isOnline());

            //If device is online, go for this
            if (((CompoundButton) toggleRain).isChecked()) {
                toggleRain.setBackgroundDrawable(getResources().getDrawable(R.drawable.stopbutton));
            } else {
                toggleRain.setBackgroundDrawable(getResources().getDrawable(R.drawable.playbutton));
            }

                    //----> HERE GOES WHERE I THINK IS THE PROBLEM <-----
                    //---------------------------------------------------
            if (isOnline()){
                //If music is not playing, start music
                if(count==0){

                    Log.d(TAG, "START PROGRESS DIALOG");
                    progressDialog = ProgressDialog.show(v.getContext(), "Load", "Loading");
                    //progressDialog = ProgressDialog.show(, "Load", "Loading...", true, false);
                    Log.d(TAG, "END PROGRESS DIALOG");
                    Log.d(TAG, "START PREPARE STREAM");
                    Context context = v.getContext();
                    prepareStream(context);
                    Log.d(TAG, "END PREPARE STREAM");
                    Log.d(TAG, "START MEDIA PLAYER START");

                            //LOG CAT START AND END ALL OF THE OTHER LOG TAGS, EXCEPT THIS mediaplayer.start()
                    mediaPlayer.start();
                    Log.d(TAG, "END MEDIAPLAYER START");
                    count = 1;
                } else {
                    mediaPlayer.pause();
                    count = 0;
                }
            }               

    } else if( buttonAbout.getId() == ((Button)v).getId() ){

        Intent i = new Intent(iFocusActivity.this, AboutActivity.class);
        startActivity(i);

    }

    else if ( buttonMethod.getId() == ((Button)v).getId() ){

        Intent o = new Intent(iFocusActivity.this, MethodActivity.class);
        startActivity(o);
    }

    else if ( buttonLink.getId() == ((Button)v).getId() ){

        Uri uri = Uri.parse( "http://getFocused.in" );
        startActivity( new Intent( Intent.ACTION_VIEW, uri ) );
    }


}

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer = null;
        }

    }


}

所以 logcat 告诉我 mediaPlayer.start() 被调用的时间 NullPointerException

最佳答案

您必须在 runOnUiThread() 方法中运行 ProgressDialog.show()(不在主 UI 线程中)。请参阅 Android 文档 here

创建一个进度对话框对象,然后编写此代码。

runOnUiThread(new Runnable(){
            @Override
            public void run() {
                dialog.show();
            }
        });

此外,调用 prepareStream()mediaplayer.start() 应该进入单独的线程,而不是主 UI 线程。

解决掉与线程相关的问题就可以了。

关于java - 线程、MediaPlayer、ProgressDialog 和上下文问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7835411/

相关文章:

java - 查找调用特定方法的代码树

android - 通过命令行 Android 使用 FFMPEG 从选定图像创建视频

Android,控制背景音的音量

android - 暂停时更新 MediaPlayer 开始位置

java - 尝试使用JavaMail

java - 使用 Java 提取 ISO 文件

java - IntelliJ 中的简单自定义重构

android - 有没有办法将图像作为位图加载到 Glide

java - Http post 获取响应 Android

android - java.lang.IllegalStateException : Not allowed to start service Intent while trying to run RingtoneService 错误