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

发布于 2024-12-10 17:11:36 字数 6626 浏览 0 评论 0原文

我已经尝试并完成了我在互联网和 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

I've tried and done everything that I read on internet and here on stackoverflow to solve my problem, but no success till now. What I'm trying to do is basically click on a button and show a ProgressDialog while the MediaPlayer is buffering a stream from internet. I got many types of erros with context stuff (NullPointerException) and thread problems too. Here are some details about the code:

  1. the button is a toggle button with background image sat based on events (on, off, not connected show different image buttons);
  2. The function prepareStream() is the one that should be ran in a thread and dismiss the ProgressDialog after load the stream. it's calling an http stream of BBC radio;
  3. I guess that the problem is about the context... I've put some Log.d TAGs on the code to check where was happening the problem and O figured out that was on mediaPlayer.start() method.

He goes the little boy:

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

    }


}

So logcat tell me on the time mediaPlayer.start() is called the NullPointerException

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甩你一脸翔 2024-12-17 17:11:36

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

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

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

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

整理好与线程相关的问题就可以了。

You must run your ProgressDialog.show() in the runOnUiThread() method(Not in the main UI thread). See the Android docs here

Create a progress dialog object and then, write this code.

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

Also the calls prepareStream() and mediaplayer.start() should go into a separate thread and not the main UI thread.

Sort out the thread related issues and you should be done.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文