Android 异步任务进度条 onProgressUpdate

标签 android android-asynctask

我是一名新程序员。我看过很多教程,但不明白哪里出了问题。我正在尝试从异步任务创建 ProgressBar。但是它总是使我的应用程序崩溃。

这是“主”应用程序:

package pt.flag.ensemble;

import java.util.Random;

import pt.flag.ensemble.task.AsyncTaskBar;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.Toast;

public class Intervals extends Activity {

    private static Intervals instance;
    private Context context;
    private String answer;
    int right_question;
    int wrong_question;
    int randomInt2;
    public ProgressBar progressBar;




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_intervals);

        // initializing the sounds
        final MediaPlayer sound1 = MediaPlayer.create(Intervals.this,
                R.raw.maj2);
        final MediaPlayer sound2 = MediaPlayer.create(Intervals.this,
                R.raw.maj3);
        final MediaPlayer sound3 = MediaPlayer.create(Intervals.this,
                R.raw.maj4);

        //ProgressBar
        instance=this;
        ProgressBar progressBar = (ProgressBar) findViewById(R.id.Progressbar);
        progressBar.setProgress(0);


        // Play Methods
        final ImageButton Play = (ImageButton) findViewById(R.id.Play);
        Play.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                new AsyncTaskBar().execute();
                Play.setEnabled(false);
                // generate random number
                Random randomGenerator = new Random();
                int randomInt = randomGenerator.nextInt(3) + 1;
                randomInt2 = randomInt;



                // picking the right sound to play
                    switch (randomInt) {
                    case 1:
                        sound1.start();
                        answer = "M2";
                        break;
                    case 2:
                        sound2.start();
                        answer = "M3";
                        break;
                    case 3:
                        sound3.start();
                        answer = "P4";
                        break;
                    }

            }
        });

        //Audio Repeat Methods
        Button Repeat = (Button) findViewById(R.id.Repeat);
        Repeat.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {



                    // picking the right sound to play
                    switch (randomInt2) {
                    case 1:
                        sound1.start();
                        new AsyncTaskBar().execute();
                        answer = "M2";
                        break;
                    case 2:
                        sound2.start();
                        new AsyncTaskBar().execute();
                        answer = "M3";
                        break;
                    case 3:
                        sound3.start();
                        new AsyncTaskBar().execute();
                        answer = "P4";
                        break;
                    }


            }
        });
    }

    //Answering Methods
    public void buttonClicked2(View view) {
        Button clickedButton = (Button) view;
        if (clickedButton.getText().toString().equals(answer)) {
            Toast.makeText(Intervals.this, "You are Right!", Toast.LENGTH_LONG)
                    .show();

            right_question = right_question + 1;


            final ImageButton Play = (ImageButton) findViewById(R.id.Play);
            Play.setEnabled(true);

            // Passing results through
            SharedPreferences sharedPref = getSharedPreferences(
                    "INTERVALRIGHTS", Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sharedPref.edit();
            editor.putInt("SCORE", right_question);
            editor.commit();

        } else {
            Toast.makeText(Intervals.this, "You are Wrong!", Toast.LENGTH_LONG)
                    .show();

            wrong_question = wrong_question + 1;

            // Passing results through
            SharedPreferences sharedPref02 = getSharedPreferences(
                    "INTERVALWRONGS", Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sharedPref02.edit();
            editor.putInt("SCORE02", wrong_question);
            editor.commit();

        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.intervals, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        switch (item.getItemId()) {
        case R.id.action_settings:
            Intent intent = new Intent(Intervals.this, IntervalResults.class);
            startActivity(intent);
            break;
        default:
            return super.onOptionsItemSelected(item);
        }
        return true;
    }

        public static Intervals getApp() { return instance; }
}

这是 AsyncTask 类

package pt.flag.eventapp.task;

import pt.flag.eventapp.Main;
import android.os.AsyncTask;
import android.os.SystemClock;
import android.widget.Toast;

public class ShowDialogAsyncTask extends AsyncTask<Void, Integer, Void> {
    int progress_status;

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
        //Toast.makeText(Main.getApp(),"Invoke on PreExecute()", Toast.LENGTH_SHORT).show();
        progress_status = 0 ;
        //Main.getApp().txt_percentage.setText("downloading 0%");
    }

    @Override
    protected Void doInBackground(Void... params) {
        while (progress_status < 100){
            progress_status +=2;
            publishProgress(progress_status);
            SystemClock.sleep(300);
        }
        return null;
    }
    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        //Main.getApp().progressBar.setProgress(values[0]);
        //Main.getApp().txt_percentage.setText("downloading" + values[0] + "%");
}
    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        //Toast.makeText(Main.getApp(), "Invoke onPostExecute()", Toast.LENGTH_SHORT).show();
        //Main.getApp().txt_percentage.setText("download complete");
    }
}

这是日志:

08-10 20:38:11.081: E/AndroidRuntime(21441): FATAL EXCEPTION: main
08-10 20:38:11.081: E/AndroidRuntime(21441): java.lang.NullPointerException
08-10 20:38:11.081: E/AndroidRuntime(21441):    at pt.flag.ensemble.task.AsyncTaskBar.onProgressUpdate(AsyncTaskBar.java:34)
08-10 20:38:11.081: E/AndroidRuntime(21441):    at pt.flag.ensemble.task.AsyncTaskBar.onProgressUpdate(AsyncTaskBar.java:1)
08-10 20:38:11.081: E/AndroidRuntime(21441):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:618)
08-10 20:38:11.081: E/AndroidRuntime(21441):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-10 20:38:11.081: E/AndroidRuntime(21441):    at android.os.Looper.loop(Looper.java:156)
08-10 20:38:11.081: E/AndroidRuntime(21441):    at android.app.ActivityThread.main(ActivityThread.java:4977)
08-10 20:38:11.081: E/AndroidRuntime(21441):    at java.lang.reflect.Method.invokeNative(Native Method)
08-10 20:38:11.081: E/AndroidRuntime(21441):    at java.lang.reflect.Method.invoke(Method.java:511)
08-10 20:38:11.081: E/AndroidRuntime(21441):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
08-10 20:38:11.081: E/AndroidRuntime(21441):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
08-10 20:38:11.081: E/AndroidRuntime(21441):    at dalvik.system.NativeStart.main(Native Method)

如果我是对的,日志似乎表明 AsyncTask 类的第 34 行有错误,即“Intervals.getApp().progressBar.setProgress(values[0]);”我只是不知道为什么...

还有,这是我的xml文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <ImageButton
        android:id="@+id/Play"
        android:contentDescription="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher"
        android:layout_marginTop="50dp"
        android:layout_marginLeft="50dp" />

    <Button
        android:id="@+id/Repeat"
        android:contentDescription="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Repeat"
        android:layout_marginTop ="50dp"
        android:layout_toRightOf="@+id/Play"
        android:layout_marginLeft="25dp" />

      <ProgressBar
        android:id="@+id/Progressbar"
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="test"
        android:layout_marginTop="20dp"
        android:layout_below="@+id/Play" />

    <Button
        android:id="@+id/Octave_Button"
        android:layout_width="52dp"
        android:layout_height="80dp"
        android:layout_marginLeft="5dp"
        android:layout_below="@+id/Progressbar"
        android:onClick="buttonClicked2"
        android:layout_marginTop="100dp" 
        android:text="@string/octave" />

    <Button
        android:id="@+id/min2_Button"
        android:layout_width="52dp"
        android:layout_height="80dp"
        android:layout_below="@+id/Progressbar"
        android:onClick="buttonClicked2"
        android:layout_marginTop="100dp" 
        android:layout_toRightOf="@+id/Octave_Button"
        android:text="@string/minor2" />

    <Button
        android:id="@+id/Maj2_Button"
        android:layout_width="52dp"
        android:layout_height="80dp"
        android:layout_below="@+id/Progressbar"
        android:onClick="buttonClicked2"
        android:layout_marginTop="100dp" 
        android:layout_toRightOf="@+id/min2_Button"
        android:text="@string/major2" />

    <Button
        android:id="@+id/min3_Button"
        android:layout_width="52dp"
        android:layout_height="80dp"
        android:layout_below="@+id/Progressbar"
        android:onClick="buttonClicked2"
        android:layout_marginTop="100dp" 
        android:layout_toRightOf="@+id/Maj2_Button"
        android:text="@string/minor3" />

    <Button
        android:id="@+id/Maj3_Button"
        android:layout_width="52dp"
        android:layout_height="80dp"
        android:layout_below="@+id/Progressbar"
        android:onClick="buttonClicked2"
        android:layout_marginTop="100dp" 
        android:layout_toRightOf="@+id/min3_Button"
        android:text="@string/major3" />

    <Button
        android:id="@+id/P4_Button"
        android:layout_width="52dp"
        android:layout_height="80dp"
        android:layout_below="@+id/Progressbar"
        android:onClick="buttonClicked2"
        android:layout_marginTop="100dp" 
        android:layout_toRightOf="@+id/Maj3_Button"
        android:text="@string/perfect4" />



    <Button
        android:id="@+id/A4_Button"
        android:layout_width="52dp"
        android:layout_height="80dp"
        android:layout_below="@+id/Octave_Button"
        android:onClick="buttonClicked2"
        android:layout_marginTop="15dp"
        android:layout_marginLeft="5dp"
        android:text="@string/tritone" />

    <Button
        android:id="@+id/P5_Button"
        android:layout_width="52dp"
        android:layout_height="80dp"
        android:layout_below="@+id/min2_Button"
        android:onClick="buttonClicked2"
        android:layout_marginTop="15dp"
        android:layout_toRightOf="@+id/A4_Button"
        android:text="@string/perfect5" />

    <Button
        android:id="@+id/minor6_Button"
        android:layout_width="52dp"
        android:layout_height="80dp"
        android:layout_below="@+id/Maj2_Button"
        android:onClick="buttonClicked2"
        android:layout_marginTop="15dp"
        android:layout_toRightOf="@+id/P5_Button"
        android:text="@string/minor6" />

     <Button
        android:id="@+id/Major6_Button"
        android:layout_width="52dp"
        android:layout_height="80dp"
        android:layout_below="@+id/min3_Button"
        android:onClick="buttonClicked2"
        android:layout_marginTop="15dp"
        android:layout_toRightOf="@+id/minor6_Button"
        android:text="@string/major6" />

    <Button
        android:id="@+id/minor7_Button"
        android:layout_width="52dp"
        android:layout_height="80dp"
        android:layout_below="@+id/Maj3_Button"
        android:onClick="buttonClicked2"
        android:layout_marginTop="15dp"
        android:layout_toRightOf="@+id/Major6_Button"
        android:text="@string/minor7" />


    <Button
        android:id="@+id/Major7_Button"
        android:layout_width="52dp"
        android:layout_height="80dp"
        android:layout_below="@+id/P4_Button"
        android:onClick="buttonClicked2"
        android:layout_marginTop="15dp"
        android:layout_toRightOf="@+id/minor7_Button"
        android:text="@string/major7" />

最佳答案

我认为将进度条作为参数传递给 AsyncTask 会更好:

final ProgressBar progressBar = (ProgressBar) findViewById(R.id.Progressbar);
progressBar.setProgress(0);

// Play Methods
final ImageButton Play = (ImageButton) findViewById(R.id.Play);
Play.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View view) {
        AsyncTaskBar task = new AsyncTaskBar();
        task.setProgressBar(progressBar);
        task.execute();
    }

然后在您的 AsyncTask 上声明 setProgressBar 方法:

public class ShowDialogAsyncTask extends AsyncTask<Void, Integer, Void> {

ProgressBar bar;

public void setProgressBar(ProgressBar bar) {
    this.bar = bar;
}

@Override
protected void onProgressUpdate(Integer... values) {
    super.onProgressUpdate(values);
    if (this.bar != null) {
        bar.setProgress(values[0]);
    }
}

您可以对您尝试设置的 TextView 执行相同的操作。

无论如何,既然您提到您是这方面的新手,您可能想看看广播/接收器模式。事情是这样的:

  1. 在不设置进度条或任何其他内容的情况下启动异步任务。
  2. 定义一个 BroadcastReceiver,在您的 Activity 中实例化一个并相应地注册/注销它。
  3. 只要您的异步任务有进度更新,只需调用 sendBroadcast 并将进度更新作为 intent extra。您可能需要在实例化 AsyncTask 时传递上下文参数。
  4. 您应用的广播接收器(您在第 2 步中实例化的接收器)的 onHandleIntent 方法将在 UI 线程上运行,确保所有这些 UI 更新安全。

听起来有点过分?一开始是这样,但有以下好处:

  1. 它比将 UI 对象传递给 AsyncTask 更简洁。
  2. 您将学习一种强大的 Android 模式,它将在其他工作中派上用场。
  3. 如果您切换上下文或您的应用程序内存不足,它将为您省去很多麻烦(和异常)。

关于Android 异步任务进度条 onProgressUpdate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25232343/

相关文章:

android - onDateChanged 方法似乎不起作用

java - 调用一堆 AsyncTask,有没有办法知道它们何时都完成显示消息?

android - Android ImageView 上的减法滤镜(从图像或 View 对象中切出羽毛状椭圆)

Android Force GPU Rendering 如何启用和禁用?

android - 将 eclipse 项目导出为 gradle

java - SQLite VACUUM 命令

android - 执行 AsyncTask doInBackground() 时在 android 中崩溃

java - AsyncTask doInBackground 中的多线程代码

android - 如何制作通用的 AsyncTask?

Android ListView 在点击切换按钮的位置获取 TextView 值