2015-02-01 2 views
0

Моя активность создает экземпляр моего отдельного класса AsyncTask и выполняет его. DoInBackground отлично работает вместе с основным видом активности в отдельных потоках, но onPostExecute вызывается только после того, как все закончилось в потоке пользовательского интерфейса. Насколько мне известно, это не должно быть так: AsyncTask должен перейти к onPostExecute, как только makeInBackground закончит и вернет значение. Вот мой код, я бы очень признателен, если кто-нибудь может сказать мне, что здесь происходит:Android AsyncTask onPostExecute называется поздно?

Во-первых, мой 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); 
    } 
} 

примечание - я должен был закомментировать слушателя, как она опиралась на onPostExecute работает по назначению

Теперь основной деятельности (соответствующая подпрограмма):

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

и, наконец, 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 

Последний системный выход из onPostExecute, после того как завершился длительный процесс в потоке пользовательского интерфейса. Любая помощь будет оценена!

ответ

1

onPostExecute() на самом деле работает в главном интерфейсе это резьбовых так что вы можете взаимодействовать с элементами, которые могут быть изменены только там, такие как текст на TextViews, убирали в ProgressBar и т.д. Порядок, в котором он работает, зависит от Сам Android, хотя он, как правило, находится в конце очереди потока.

Вот несколько простых исправлений:

  • Делайте то, что вы хотели бы сделать в потоке без UI изнутри doInBackground(), если это возможно
  • Запуск другой AsyncTask с конца onPostExecute() и проход это все необходимые данные
  • Начать свой собственный новый поток + работоспособная
+0

Хорошо это проясняет много вещей, но я не уверен, что вы имеете в виду о запуске другого AsyncTask п rom onPostExecute. Мой AsyncTask - это отдельный класс, и я бы хотел работать в нескольких действиях. Можно ли дать мне пример того, как использовать onPostExecute для возврата ResultSet к моей активности? Это было бы абсолютно фантастично !!! Я пытался использовать интерфейс, но он не работал – user3925417

+0

Зависит от того, что вы подразумеваете под несколькими действиями. У меня есть несколько примеров моего GitHub (из одного репо на самом деле), которые я мог бы связать, которые довольно просты. Однако, если вы хотите, чтобы одно действие вызывало AsyncTask и другое действие для получения данных, это немного сложнее - должна быть постоянная ссылка, которую AsyncTask может отправлять данным, то есть одноэлементный или просто расширяющий Заявка. Если это последний, это немного более пример и, возможно, нужен еще один новый вопрос? Если это первая ситуация, я могу просто добавить примеры сюда ~ – MDragon00

Смежные вопросы