Android异步任务进度条onProgressUpdate

时间:2014-08-10 19:42:49

标签: 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" />

3 个答案:

答案 0 :(得分:6)

我认为将进度条作为参数传递给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,在您的活动中实例化一个并相应地注册/取消注册。
  3. 每当您的异步任务有进度更新时,只需将进度更新作为额外意图调用sendBroadcast。在实例化AsyncTask时,您可能需要传递上下文参数。
  4. 应用广播接收器的onHandleIntent方法(您在第2步实例化的方法)将在UI线程上运行,使所有这些UI更新安全。
  5. 听起来有点压倒性的?起初,但有以下好处:

    1. 它比将UI对象传递给AsyncTask要清晰得多。
    2. 您将学习一种强大的Android模式,它将在其他方面发挥作用。
    3. 如果您切换上下文或者您的应用内存不足,它将为您节省很多麻烦(和例外)。

答案 1 :(得分:1)

Intervals.getApp().progressBar.setProgress(values[0]);

此代码行中NullPointerException有两种可能性:

  1. getApp()返回null
  2. progressBarnull
  3. 为了确定原因,您需要将其分成两行:

    Intervals intervals = Intervales.getApp();
    intervals.progressBar.setProgress(values[0]);
    

    现在在第一行设置一个断点,然后跳过它,并确定intervals是否为null

答案 2 :(得分:-2)

progressBar是一个局部变量,而您引用的是另一个类对象的同名变量(在您的情况下是app对象)。你可能把它们搞混了。