2

I have my first class, its a loading screen.

 public class Loading extends Activity {

public int switchscreensvalue = 0;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.loadinglayout);

    new Loadsounds().execute(switchscreensvalue);


            if (switchscreensvalue == 1)
            {
                Intent myIntent = new Intent(Loading.this, main.class);
                startActivityForResult(myIntent, 0);
            }



        }
}

Then I have my asynctask class.

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

@Override
protected Void doInBackground(Integer... params) {

        SoundManager.addSound(0, R.raw.rubber);
    SoundManager.addSound(1, R.raw.metal);
    SoundManager.addSound(2, R.raw.ice);
    SoundManager.addSound(3, R.raw.wind);
    SoundManager.addSound(4, R.raw.fire);

    return null;
}


protected void onPostExecute(Integer...params){
    int switchscreensvalue = 1;
}

 }

I want it to start the asynctask, which loads 5 sounds into a soundboard, and when its done, change the int "switchscreensvalue" to 1. Then, the loading screen is supposed to change to the main screen when "switchscreensvalue" = 1. It does not work though. Please can anyone help me, just learning asynctasks for the first time. Still fairly new to Java in fact. I need the asynctask to load 5 sounds and then change the activity from loading to main activity.

codesomethin
  • 195
  • 1
  • 3
  • 11

4 Answers4

3

Thats because you are calling

 if (switchscreensvalue == 1)
        {
            Intent myIntent = new Intent(Loading.this, main.class);
            startActivityForResult(myIntent, 0);
        }

in your onCreate() which you cant gaurantee will be called again.

Why dont you call

 if (switchscreensvalue == 1)
        {
            Intent myIntent = new Intent(Loading.this, main.class);
            startActivityForResult(myIntent, 0);
        }

In your onPostExecute() after you set the variable as it should be.

coder_For_Life22
  • 26,645
  • 20
  • 86
  • 118
  • 2
    Remeber the asynctask isnt run on the man thread, so after the onCreate executes the asynctask it is going to keep running through your code, so when the asynctask is finished the onCreate has already done its check on the variable. – coder_For_Life22 Jan 06 '12 at 00:57
  • What do you mean change Loading to main?(in the comment answer below) – coder_For_Life22 Jan 06 '12 at 01:29
  • I mean I need to change the acticity from Loading.class to Main.class. But I can't figure out how to do that if I am in asynctask.class – codesomethin Jan 06 '12 at 01:47
2

This should work...

public class Loading extends Activity {

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

        new Loadsounds().execute();
    }

    public void startMainActivity() {
        Intent myIntent = new Intent(this, Main.class);
        startActivityForResult(myIntent, 0);
    }

    private class Loadsounds extends AsyncTask<Void, Void, Boolean> {
        boolean success = false;

        @Override
        protected Void doInBackground(Void... params) {
            // Load sounds here and set success = true if successful
        }
        return success;

        @Override
        protected void onPostExecute(Boolean...result) {
            if (result)
                startMainActivity();
        }
    }
)
Dheeraj Vepakomma
  • 26,870
  • 17
  • 81
  • 104
Squonk
  • 48,735
  • 19
  • 103
  • 135
  • 2
    This worked very well sir. You just taught me about a few essential ideas about classes and asynctasks. Many thanks to 0909EM and coder_for_life also. I am going to bookmark this page and remember you guys/girls forever! – codesomethin Jan 06 '12 at 02:07
  • My first attempts at using `AsyncTask` were a bit of disaster. I learned the tricks here on SO and I figure it's only fair to pass them on. The easiest way to use `AsyncTask` is as I showed above - make it a nested/inner class of your `Activity`. That way it can access all of your the `Activity` fields and methods using `onPreExecute`, `onProgressUpdate`, `onPostExecute` etc. It is possible to create stand-alone `AsyncTask` sub-classes but that get's more complicated. Good luck. – Squonk Jan 06 '12 at 02:17
  • Actually I've just edited my code to change `startActivity` to `startMainActivity` so it isn't confused with the existing `startActivity` - I suggest you do the same. – Squonk Jan 06 '12 at 02:20
1

Your almost there... Lose the variable...

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.loadinglayout);
    new Loadsounds().execute(switchscreensvalue);
}


//                                       <Params, Progress, Result>
public class Loadsounds extends AsyncTask<Integer, Integer, Integer> {

@Override
protected Void doInBackground(Integer... params) {

    int result = 0;
    try {
        SoundManager.addSound(0, R.raw.rubber);
        SoundManager.addSound(1, R.raw.metal);
        SoundManager.addSound(2, R.raw.ice);
        SoundManager.addSound(3, R.raw.wind);
        SoundManager.addSound(4, R.raw.fire);
        result = 1;
    } catch(Exception e){
        // some error handling if SoundManager.addSound throws exceptions?
    }

    return result; // positive integer on success
}


protected void onPostExecute(Integer result){
    if (!isCancelled() && (result != null) && (result > 0)
    {
        // int someResult = 0;
        Intent myIntent = new Intent(Loading.this, main.class);
        // should the following line be startActivity? 
        // difference between startActivity and startActivityForResult 
        // is that the latter returns an integer value where your zero is
        //startActivityForResult(myIntent, 0);
        startActivityForResult(myIntent, someResult);

        // Alternatively, just...
        // startActivity(myIntent);
    } else {
        // Log error, inform user, then close application?
    }

}

}
0909EM
  • 4,761
  • 3
  • 29
  • 40
  • Urgh.... Been beaten to it... Sorry @coder_For_Life22 seems that we've both got the same answer... – 0909EM Jan 06 '12 at 01:04
  • Yes but the problem is, in the code : Intent myIntent = new Intent(Loading.this, main.class); this isn't in the class "Loading" its in a separate class. How do I fix this so it changes Loading to Main? – codesomethin Jan 06 '12 at 01:23
  • If I'm not mistaken, "Loading.this" is how you reference the "Loading" class from the AsyncTask (when the AsyncTask resides in the same Java file as the Loading Activity)... Alternatively, Intent myIntent = new Intent(getApplication(), Main.class); which uses the application's context to the "Main" activity... Otherwise I've misunderstood your comment... – 0909EM Jan 06 '12 at 01:34
  • 1
    @0909EM: Calling `isCancelled()` in `onPostExecute(...)` isn't necessary. The reasoning is that `isCancelled()` will only return `true` if at some point `cancel(true)` has been called on the `AsyncTask`. If this is actually the case then `onPostExecute(...)` is never called and `onCancelled()` will be called instead. – Squonk Jan 06 '12 at 01:37
  • My loading screen activity is in one class and I looked at the android developer website and it said to make a NEW class to make the asynctask. Now when I try to use Intent myIntent = new Intent(Loading.this, main.class); in my asynctask class, it says there it is not in an accessible scope. this is what I have right now for the onPostExecute protected void onPostExecute(Integer result){ if (!isCancelled() && (result != null) && (result > 0)) { Intent myIntent = new Intent(Loading.this, dirtynames.class); startActivityForResult(myIntent, 0); } } – codesomethin Jan 06 '12 at 01:40
  • @MisterSquonk Yes. isCancelled() is redundant. I've just had a look at the documentation at http://developer.android.com/reference/android/os/AsyncTask.html and you are correct. But there is a question about this on stack overflow, which seems to suggest that onPostExecute gets called anyway... Having looked at the source in AsyncTask (for Android 4) it appears that onPostExecute does not get called anyway... http://stackoverflow.com/questions/3334858/onpostexecute-on-cancelled-asynctask – 0909EM Jan 06 '12 at 01:43
  • I mean I need to change the acticity from Loading.class to Main.class. But I can't figure out how to do that if I am in asynctask.class – codesomethin Jan 06 '12 at 01:48
  • @0909EM: Interesting point WRT that SO question. I agree with the source I just looked at I can't see how `onPreExecute` might be called if the task has been cancelled despite what they say in that question. I suppose it might always be useful to do the checks as in your code. I've never had problems myself though. – Squonk Jan 06 '12 at 02:23
0

I think what your trying to say is that it's not switching activity? I hear what you say about scope, are you sure both classes are in the same file? ie, one class (LoadingTask) inside another (Loading class)?

try switching "Loading.this" for "getApplication()"

I have

public class Loading extends Activity {
protected void onCreate(...){
    ... (As in above answer)
}

// LoadTask exists inside the Loading activity class
private class LoadTask extends AsyncTask<Integer, Integer, Integer>     {
    protected Integer doInBackground(Integer... params) {
        ... (As in above answer)
    }

    protected void onPostExecute(Integer result) {
        super.onPostExecute(result);
        try {
            Intent intent = new Intent(Loading.this, Main.class);
            // Alternatively
            // Intent intent = new Intent(getApplication(), Main.class);
            startActivity(intent);
        } catch (ActivityNotFoundException e){
            // Exception handling code
        }
    } 
}
}
0909EM
  • 4,761
  • 3
  • 29
  • 40