首页 > 解决方案 > Android AsyncTask:“执行 doInBackground() 时发生错误”

问题描述

我在理解这里发生的事情时遇到了一些问题,因此非常感谢任何帮助。我对 Android 开发有点陌生。

这些是我收到的错误:

E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
              Process: com.example.benignfella.workorganizer, PID: 9956
              java.lang.RuntimeException: An error occured while executing doInBackground()
                  at android.os.AsyncTask$3.done(AsyncTask.java:300)
                  at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
                  at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
                  at java.util.concurrent.FutureTask.run(FutureTask.java:242)
                  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
                  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
                  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
                  at java.lang.Thread.run(Thread.java:841)
               Caused by: java.lang.NullPointerException
                  at com.example.benignfella.workorganizer.Fragment.RecordsListFragment$GetRecordsTask.doInBackground(RecordsListFragment.java:87)
                  at com.example.benignfella.workorganizer.Fragment.RecordsListFragment$GetRecordsTask.doInBackground(RecordsListFragment.java:77)
                  at android.os.AsyncTask$2.call(AsyncTask.java:288)
                  at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
                  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
                  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
                  at java.lang.Thread.run(Thread.java:841) 

这是显然有问题的类(从第 77 行开始,如 所述RecordsListFragment.java:77

public class GetRecordsTask extends AsyncTask<Void, Void, ArrayList<Records>> {

    private final WeakReference<Activity> activityWeakRef;

    public GetRecordsTask(Activity context) {
        this.activityWeakRef = new WeakReference<Activity>(context);
    }

    @Override
    protected ArrayList<Records> doInBackground(Void... arg0) {
        ArrayList<Records> recordsArrayList = recordsDAO.getRecords();
        return recordsArrayList;
    }

    @Override
    protected void onPostExecute(ArrayList<Records> empList) {
        if (activityWeakRef.get() != null && !activityWeakRef.get().isFinishing()) {
            records = empList;
            if (empList != null) {
                if (empList.size() != 0) {
                    recordsListAdapter = new RecordsListAdapter(activity, empList);
                    recordsListView.setAdapter(recordsListAdapter);
                } else {
                    Toast.makeText(activity, "No Records about records... wait wot m8?",
                            Toast.LENGTH_LONG).show();
                }
            }
        }
    }
}

该方法的错误点doInBackground,更具体地说,这一行:

ArrayList<Records> recordsArrayList = recordsDAO.getRecords();

我读过一些关于将代码块传递给onPostExecute方法的内容,但我不确定如何。如果有人可以帮助我解决这个问题,那就太好了。

编辑:提议的线程没有解决我的问题我发布问题的原因是我自己无法解决问题。

根据线程,可能会发生 NPE,因为我假设该对象是在调用该方法之前创建的,但这不是我在这里所做的:public class GetRecordsTask extends AsyncTask<Void, Void, ArrayList<Records>>

我真的不明白我做错了什么,所以我真的在寻求一些具体的帮助。

编辑 2:这是 RecordsDAO 类的全部内容

public class RecordsDAO extends RecordsDBDAO {

    public static final String RECORDS_ID_WITH_PREFIX = "records.id";

    private static final String WHERE_ID_EQUALS = DatabaseHelper.ID + " =?";

    private static final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);

    //Constructor
    public RecordsDAO(Context context) {
    super(context);
    }

    public long save(Records records) {
    //Use ContentValues to access database
    ContentValues values = new ContentValues();

    //Should I add the ID field as well?
    values.put(DatabaseHelper.DESCRIPTION, records.getDescription());
    values.put(DatabaseHelper.KEY_CREATED_AT, formatter.format(records.getDateofRecord()));
    values.put(DatabaseHelper.STARTINGHOUR, records.getStart());
    values.put(DatabaseHelper.FINISHINGHOUR, records.getFinish());
    values.put(DatabaseHelper.COMMENTS, records.getComments());

    return database.insert(DatabaseHelper.TABLE_RECORDS, null, values);
    }

    public long update(Records records) {
    //Use ContentValues to access database
    ContentValues values = new ContentValues();
    values.put(DatabaseHelper.DESCRIPTION, records.getDescription());
    values.put(DatabaseHelper.KEY_CREATED_AT, formatter.format(records.getDateofRecord()));
    values.put(DatabaseHelper.STARTINGHOUR, records.getStart());
    values.put(DatabaseHelper.FINISHINGHOUR, records.getFinish());
    values.put(DatabaseHelper.COMMENTS, records.getComments());

    long result = database.update(
            DatabaseHelper.TABLE_RECORDS,
            values,
            WHERE_ID_EQUALS,
            new String[] {
                    String.valueOf(records.getId())
            }
    );

    return result;
    }

    public int deleteRecord(Records records) {
    return database.delete(DatabaseHelper.TABLE_RECORDS,
            WHERE_ID_EQUALS,
            new String[] {
                    records.getId() + ""
            });
    }

    public ArrayList<Records> getRecords() {
    ArrayList<Records> records = new ArrayList<Records>();

    String query = "SELECT " + RECORDS_ID_WITH_PREFIX + ", "
            + DatabaseHelper.DESCRIPTION + " ,"
            + DatabaseHelper.KEY_CREATED_AT + ", "
            + DatabaseHelper.STARTINGHOUR + ", "
            + DatabaseHelper.FINISHINGHOUR + ", "
            + DatabaseHelper.COMMENTS + " FROM "
            + DatabaseHelper.TABLE_RECORDS + " rec,"
            + DatabaseHelper.TABLE_LOCATIONS + " loc,"
            + DatabaseHelper.TABLE_TAGS + " tg WHERE rec."
            + DatabaseHelper.LOCATIONS_ID + " = loc." + DatabaseHelper.ID + " AND "
            + DatabaseHelper.TAGS_ID + " = tg." + DatabaseHelper.ID;

    Cursor cursor = database.rawQuery(query, null);

    while (cursor.moveToNext()) {
        Records records1 = new Records();
        records1.setId(cursor.getInt(0));
        records1.setDescription(cursor.getString(1));

        try {
            records1.setDateofRecord(formatter.parse(cursor.getString(2)));
        } catch (ParseException e) {
            records1.setDateofRecord(null);
        }

        records1.setStart(cursor.getString(3));
        records1.setFinish(cursor.getString(4));
        records1.setComments(cursor.getString(5));

        Locations locations = new Locations();
        locations.setId(cursor.getInt(6));
        locations.setLocation(cursor.getString(7));

        Tags tags = new Tags();
        tags.setId(cursor.getInt(8));
        tags.setName(cursor.getString(9));

        records1.setLocations(locations);
        records1.setTags(tags);
        records.add(records1);
    }
    return records;
    }

    public void loadTags() {
    Tags tag = new Tags("Ljubljana, Faculty");
    Tags tag1 = new Tags("Kranj, OpenLab");
    Tags tag2 = new Tags("Ljubljana, Other");
    Tags tag3 = new Tags("Kranj, Other");

    List<Tags> tagsList = new ArrayList<Tags>();
    tagsList.add(tag);
    tagsList.add(tag1);
    tagsList.add(tag2);
    tagsList.add(tag3);

    for (Tags tg : tagsList) {
        ContentValues values = new ContentValues();
        values.put(DatabaseHelper.TAGS, tg.getName());
        database.insert(DatabaseHelper.TABLE_TAGS, null, values);
    }
    }
}

解决方案

正如@Mangal 所指出的,我的错误在于没有完全初始化RecordsDAO,因此出现了空指针异常。包含类的GetRecordsTask类确实声明了

RecordsDAO recordsDAO;

但这是不完整的初始化。实际上应该是

RecordsDAO recordsDAO = new RecordsDAO(getActivity());

解决了我的问题。非常感谢您帮助我解决这个问题,问题解决了。

标签: javaandroidandroid-asynctasknullpointerexception

解决方案


ArrayList<Records> recordsArrayList = recordsDAO.getRecords();

这条线对我来说也很可疑。您也应该发布recordsDAO的课程。我建议您仔细检查您的 recordsDAO 的 getRecords() 方法。
我想对此发表评论,但我不能。


推荐阅读