Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Async Task Progress Bar onProgressUpdate

I am a new programmer. I have seen lots of tutorials but can't understand what is wrong. I am trying to create a ProgressBar from an Async Task. However it always crashes my application.

Here is the "main" app:

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

Here is the AsyncTask class

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

Here is the Log:

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)

If I am correct, the log seems to indicate an error in line 34 at the AsyncTask class, which is "Intervals.getApp().progressBar.setProgress(values[0]);" I just don't know why...

Also, here is my xml file

<?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" />
like image 686
André Martinho Avatar asked Mar 20 '26 08:03

André Martinho


1 Answers

I think it's better if you pass the progress bar as an argument to the 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();
    }

And then on your AsyncTask declare the setProgressBar method:

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

You could do the same with the TextView you're trying to set.

In any case, since you mentioned you're new at this you may want to take a look at the Broadcast/Receiver pattern. Here's how it goes:

  1. Start the async task without setting the progress bar or anything.
  2. Define a BroadcastReceiver, instantiate one in your activity and register/unregister it accordingly.
  3. Whenever there's a progress update on your async task just call sendBroadcast with the progress update as an intent extra. You may need to pass a context parameter when instantiating the AsyncTask.
  4. The onHandleIntent method of your app's broadcast receiver (the one you instantiated on step 2) will run on the UI thread, making all those UI updates safe.

Sounds a bit overwhelming? It is at first, but here are the benefits:

  1. It is much cleaner than passing UI objects to an AsyncTask.
  2. You will learn a powerful Android pattern that will come in handy in other endeavours.
  3. It will save you a lot of hassle (and exceptions) if you switch context or your app is low on memory.
like image 104
jlhonora Avatar answered Mar 22 '26 21:03

jlhonora