即使在UI线程中初始化,Asynctask也无法访问onPostExecute

时间:2015-01-30 12:49:10

标签: java android multithreading android-asynctask

我正在创建一个应用程序,它在一个单独的类中使用asynctask查询数据库。此类接受一个字符串,传递字符串(应该是一个查询)并将结果作为ResultSet获取。然后应该将此ResultSet传递给onPostExecute,它使用接口将结果返回到主线程。但是,使用log命令我发现asynctask永远不会到达onPostExecute。有人可以帮我吗?

我的Asynctask类(不再使用getMyResults(),并且doInBackground中的代码无关紧要):

编辑:编辑

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

//Code to get the database connection working

    try{
        rs = st.executeQuery(Query);
        System.out.println("Records from Database");
        /*
        while(rs.next()){

            String StudentID = rs.getString("StudentID");
            String StudentName = rs.getString("StudentName");
            String StudentPassword = rs.getString("StudentPassword");
            System.out.println("Student ID: "+StudentID+"   Student Name: "+StudentName+"    Student Password: "+StudentPassword);
        }
        */
    }catch(Exception ex){
        System.out.println(ex);
    }

    System.out.println("Finished DBConnector");


    return rs;
}

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

}

我的界面(在它自己的文件中 - 是它的意思是什么?):

public interface CallBackListener {
   void processFinish(ResultSet output);
        }

最后我的活动,我遗漏了所有不相关的代码:

public class CheckTimetable extends Activity implements CallBackListener {
    ResultSet rs= null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_check_timetable);

        try {
            Class.forName("android.os.AsyncTask");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

//这被添加为修复我的问题的建议,但无济于事。

    btnBuildTimetable.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
                BuildTable(rows, cols, "A"); //need mapping system to get TutorID from spinner and send it here

//在我的原始代码行和cols中是从2个edittexts获得的整数                 }

        }
    });

}


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 = "";
connect.execute("SELECT * FROM Lessons WHERE Lessons.TutorID = '"+ GivenTutorID + "';");
connect.DBlistener = this;//should use TutorID here
    /*
try {
    Thread.sleep(5000);//just used so that the resultset doesn't get no results - waits for connect.execute to finish.
}
catch (Exception e) {}
*/
    System.out.println("WE GO IN BOYS");
while (rs == null ){
    try {
        Thread.sleep(100);
    } catch (Exception e){}
}

rs = connect.getMyResults();

for (int i=1; i<=rows; i++){
    TableRow row = new TableRow(this);
    row.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
    for (int j=1; j<=cols;j++){
        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");
            }
        }catch(Exception ex) {
            System.out.println("caught exception");
        }
        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(LessonDate);
        System.out.println(LessonDate);
        System.out.println("Cell set");

            row.addView(tv);

        }
tblTutorTimetable.addView(row);
    }
    }
        @Override
        public void processFinish(ResultSet output) {
            rs = output;
            System.out.println("WE MADE IT");
        }

当按下BuildTable按钮时,它会遍历代码,执行asynctask然后等待,直到ResultSet不为null。第二个线程(asynctask)一直持续到doInBackground结束,之后没有任何事情发生,UI线程仍然被冻结。

对于这个或界面的任何帮助都太棒了!

1 个答案:

答案 0 :(得分:0)

  

当按下BuildTable按钮时,它会遍历代码,执行asynctask然后等待,直到ResultSet不为null。第二个线程(asynctask)一直持续到doInBackground结束,之后没有任何事情发生,UI线程仍然被冻结。

不要自己等待你的asynctask。特别是不要使用Thread.sleep()阻止UI线程。

异步任务onPostExecute()在UI线程上运行,当你自己阻止线程时,它永远不会有机会运行。

相反,以异步方式使用异步任务:让UI线程执行它正在执行的操作并将控制权返回给UI线程循环器/处理程序,并使用异步任务更新UI onPostExecute()