user3925417
user3925417

Reputation: 75

Android AsyncTask onPostExecute called late?

My activity creates an instance of my separate AsyncTask class and executes it. DoInBackground runs fine alongside the main activity in separate threads, but onPostExecute is only called after everything has finished in the UI thread. To my knowledge, this should not be the case: the AsyncTask should move to onPostExecute as soon as doInBackground has finished and returned a value. Here's my code, I'd really appreciate it if anyone could tell me what's going on here:

Firstly my AsyncTask:

package com.theo.mcginley.comp4prototype;

import android.os.AsyncTask;
import java.sql.*;


public class DBConnector extends AsyncTask <String, Void, ResultSet> {

    private Connection con;
    private Statement st;
    private ResultSet rs;
  //  public CallBackListener DBlistener;



    public ResultSet getMyResults(){
        return rs;
    }

    //public


    @Override
    protected ResultSet doInBackground(String... params) {

String Query = params[0];
        System.out.println("Starting DBConnector");
        try{
            Class.forName("com.mysql.jdbc.Driver");
        }catch(Exception ex){
            System.out.println("Error: "+ex);
        }


        try{
            con = DriverManager.getConnection("jdbc:mysql://musictimetables.cdo3zf9dx3fx.us-west-2.rds.amazonaws.com:3306/music?user=Admin&password=password");
            st = con.createStatement();
        }catch(Exception ex) {
            System.out.println("Error: " + ex);
        }

        System.out.println("Connected");


        try{
            rs = st.executeQuery(Query);
            System.out.println("Records from Database");
        }catch(Exception ex){
            System.out.println(ex);
        }

        System.out.println("Finished DBConnector");
        if (rs==null){
            System.out.println("ITS NULL");
        } else{
            System.out.println("ITS NOT NULL");
        }

        return rs;
    }

    @Override
    protected void onPostExecute(ResultSet myrs) {
      //  super.onPostExecute(myrs);
        System.out.println("THIS IS WHERE IT ALL GOES WRONG");
      //  DBlistener.processFinish(myrs);
    }
}

note - I had to comment out the listener as it relied on onPostExecute working as intended

Now the main activity (relevant subroutine):

private void BuildTable(int rows, int cols, String GivenTutorID) {
        DBConnector connect = new DBConnector();
        String StudentID = "";
        String TutorID = "";
        String VenueLocation = "";
        String LessonDate = "";
        String LessonStartTime = "";
        String LessonEndTime = "";
        List<String> AllTheDates = new ArrayList<String>();
        Integer count = 0;

        connect.execute("SELECT * FROM Lessons WHERE Lessons.TutorID = '" + GivenTutorID + "';");
        try {
            Thread.sleep(4000);//just used so that the resultset doesn't get no results - waits for connect.execute to finish.
        } catch (Exception e) {
        }

        try {
            Thread.sleep(4000);//just used so that the resultset doesn't get no results - waits for connect.execute to finish.
        } catch (Exception e) {
        }
        try {
            Thread.sleep(4000);//just used so that the resultset doesn't get no results - waits for connect.execute to finish.
        } catch (Exception e) {
        }




        System.out.println("Attempting to get ResultSet");

        try {
            rs = connect.getMyResults();
            System.out.println("so far so good");
        } catch(Exception e){
            System.out.println("caught exception1: " + e);
        }

        System.out.println("through to the other side");
        System.out.println("Finished DBConnector");

        if (rs==null){
            System.out.println("ITS STILL NULL");
        } else{
            System.out.println("ITS STILL NOT NULL");
        }

            try {
                while (rs.next()) {
                    StudentID = rs.getString("StudentID");
                    TutorID = rs.getString("TutorID");
                    VenueLocation = rs.getString("VenueLocation");
                    LessonDate = rs.getString("LessonDate");
                    LessonStartTime = rs.getString("LessonStartTime");
                    LessonEndTime = rs.getString("LessonEndTime");
                    AllTheDates.add(count,LessonDate);
                    count++;

                }
            }catch(Exception ex) {
                System.out.println("caught exception2: " + ex + "  xd xDDD   " +count);
            }
        System.out.println("ejgwiw");
        BuildRow(AllTheDates.toArray(new String[AllTheDates.size()]));

}


    private void BuildRow(String...params){
        TableRow row = new TableRow(this);
        row.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
    try {
        for (Integer i = 0; i < params.length; i++) {
            TextView tv = new TextView(this);
            tv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
                    LayoutParams.WRAP_CONTENT));
            tv.setBackgroundResource(R.drawable.cell_shape);
            tv.setPadding(5, 5, 5, 5);
            tv.setText(params[i]);
            System.out.println(params[i] + " run " + i);
            row.addView(tv);
        }
        try {
            tblTutorTimetable.addView(row);
        } catch (Exception ex) {
            System.out.println(ex);
        }
    } catch (Exception ex){
        System.out.println(ex);
    }
    }

and finally the logcat:

02-01 19:26:45.092  10317-10494/com.theo.mcginley.comp4prototype I/System.out﹕ Starting DBConnector
02-01 19:26:48.223  10317-10494/com.theo.mcginley.comp4prototype I/System.out﹕ Connected
02-01 19:26:48.423  10317-10494/com.theo.mcginley.comp4prototype I/System.out﹕ Records from Database
02-01 19:26:48.423  10317-10494/com.theo.mcginley.comp4prototype I/System.out﹕ Finished DBConnector
02-01 19:26:48.423  10317-10494/com.theo.mcginley.comp4prototype I/System.out﹕ ITS NOT NULL
02-01 19:26:57.462  10317-10317/com.theo.mcginley.comp4prototype I/System.out﹕ Attempting to get ResultSet
02-01 19:26:57.462  10317-10317/com.theo.mcginley.comp4prototype I/System.out﹕ so far so good
02-01 19:26:57.462  10317-10317/com.theo.mcginley.comp4prototype I/System.out﹕ through to the other side
02-01 19:26:57.462  10317-10317/com.theo.mcginley.comp4prototype I/System.out﹕ Finished DBConnector
02-01 19:26:57.462  10317-10317/com.theo.mcginley.comp4prototype I/System.out﹕ ITS STILL NOT NULL
02-01 19:26:57.482  10317-10317/com.theo.mcginley.comp4prototype I/System.out﹕ ejgwiw
02-01 19:26:57.492  10317-10317/com.theo.mcginley.comp4prototype I/System.out﹕ 2015-01-05 run 0
02-01 19:26:57.492  10317-10317/com.theo.mcginley.comp4prototype I/System.out﹕ 2015-01-05 run 1
02-01 19:26:57.492  10317-10317/com.theo.mcginley.comp4prototype I/Choreographer﹕ Skipped 757 frames!  The application may be doing too much work on its main thread.
02-01 19:26:57.542  10317-10317/com.theo.mcginley.comp4prototype I/System.out﹕ THIS IS WHERE IT ALL GOES WRONG

The last system out is from the onPostExecute, after the lengthy process on the UI thread has finished. Any help would be appreciated!

Upvotes: 0

Views: 715

Answers (1)

MDragon
MDragon

Reputation: 1886

onPostExecute() actually runs in the main UI thread- this is so you can interact with elements that can only be edited from there, such as text on TextViews, clearing away a ProgressBar, etc. The order in which it runs depends on Android itself, although it tends to be at the end of the thread's queue.

Here are a few simple fixes:

  • Do what you would like to do in the non-UI thread from within doInBackground(), if possible
  • Start up another AsyncTask from the end of onPostExecute() and pass it any necessary data
  • Start up your own new thread+runnable

Upvotes: 1

Related Questions