简体   繁体   中英

App not displaying data loaded from database in Android

I'm working on an Android app that displays students' grade after fetching the data from a server. Upon exiting, the app persists the data in a local database so that it can be reloaded on the next startup. To store the data that I have created two tables, student and course. Student-Course tables have one-to-many relationship

I created a custom AsyncTaskLoader to load the data. Two classes extend this custom loader, one called StudentLoader which loads student data from the student table and another called CourseLoader which loads courses for a particular student (there is a student id foreign key in course table) from the course table.

Here are the custom loader classes

    //Student Loader Class
public class StudentLoader extends DataLoader<Student> {

    private String mSid;
    private StudentDbAdapter dbAdapter;


    public StudentLoader(Context context, String sid) {
        super(context);
        mSid = sid;
        dbAdapter = new StudentDbAdapter(context);
    }


    @Override
    public Student loadInBackground() {
        return dbAdapter.queryStudent(mSid);
    }
}

//Course Loader class
public class CoursesLoader extends DataLoader<ArrayList<Course>> {

    private long mId;
    private StudentDbAdapter dbAdapter;

    public CoursesLoader(Context context, long id)
    {
        super(context);
        mId = id;
        dbAdapter = new StudentDbAdapter(context);
    }

    @Override
    public ArrayList<Course> loadInBackground() {
        return dbAdapter.getCourses(mId);
    }
}

On startup, I used two LoaderCallback classes to asynchronously(and separately) load both student and courses data and update the UI based on the returned results. I put the LoaderCallback classes in the fragment that displays the student grades.

Here are LoaderCallback classes

 private class StudentLoaderCallbacks implements LoaderManager.LoaderCallbacks<Student>{


        @Override
        public Loader<Student> onCreateLoader(int i, Bundle bundle) {
            return new StudentLoader(getActivity(), mId);
        }

        @Override
        public void onLoadFinished(Loader<Student> loader, Student student) {
            mStudent = student;
            Log.d(TAG, "Finished Loading data...");
            updateUI(mStudent);
        }

        @Override
        public void onLoaderReset(Loader<Student> loader) {

        }
    }

    private class CoursesLoaderCallbacks implements LoaderManager.LoaderCallbacks<ArrayList<Course>>
    {

        @Override
        public Loader<ArrayList<Course>> onCreateLoader(int i, Bundle bundle) {
            return new CoursesLoader(getActivity(), _id);
        }

        @Override
        public void onLoadFinished(Loader<ArrayList<Course>> loader, ArrayList<Course> courses) {
           mStudent.setCourses(courses);
        }

        @Override
        public void onLoaderReset(Loader<ArrayList<Course>> loader) {

        }
    }

The app loads but doesn't display the view and only presents an empty white screen. Here is the updateUI method that updates the UI after the data has been loaded.

updateUI method

private void updateUI(Student student)
    {
        if (student == null)
        {
            showProgressDialog(true);
            return;
        }
        showProgressDialog(false);
        ArrayList<StudentVm> studentVms = new ArrayList<>();
        ArrayList<Course> courses =  student.getCourses();
        for (Course course : courses) {
            StudentVm studentVm = new StudentVm(student.getmId(), course.getName(), Integer.valueOf(course.getCredit()).toString(), course.getGrade());
            studentVms.add(studentVm);
        }

        Log.d(TAG, "About to display data...");

        GradeListAdapter gradeAdapter = new GradeListAdapter(studentVms);
        setListAdapter(gradeAdapter);

    }

What is keeping the fragment from displaying the data? Has anyone experienced this before? How to solve this?

Edit 1: Here is the method that loads student data from the db:

public  Student queryStudent(String id)
    {
        Student stu = new Student();
        Cursor cursor = db.query(DbConstants.STU_TABLE,
                null, // all columns
                DbConstants.STU_COLUMN_ID + "= ?", // look for a student ID
                new String[]{id}, // with this value
                null, // group by
                null, // order by
                null, // having
                "1"); // limit 1 row)

         cursor.moveToFirst();
        int _id = 0;
        while (!cursor.isAfterLast())
        {
            _id = cursor.getInt(cursor.getColumnIndex("_id"));
            stu.setmId(cursor.getString(cursor.getColumnIndexOrThrow(DbConstants.STU_COLUMN_ID)));
            stu.setFull_name(cursor.getString(cursor.getColumnIndexOrThrow(DbConstants.COLUMN_FNAME)));
            stu.setAcademic_year(cursor.getInt(cursor.getColumnIndexOrThrow(DbConstants.COLUMN_ACYEAR)));
            stu.setDepartment(cursor.getString(cursor.getColumnIndexOrThrow(DbConstants.COLUMN_DEPT)));
            stu.setYear(cursor.getInt(cursor.getColumnIndexOrThrow(DbConstants.COLUMN_YEAR)));
        }

        cursor.close();
        stu.set_id(_id);
        return stu;
    }

Also the logcat keeps displaying following message even after I close the app in the emulator.

Logcat消息

After the analyzing the code again, I found the error to be a rather simple mistake which was that I forgot to add cursor.moveToNext() in the while loop in which the student data is loaded. This resulted in an infinite loop which stopped the app from loading data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM