如何使 AsyncTask“doInBackground()”等待一个数组列表
Posted
技术标签:
【中文标题】如何使 AsyncTask“doInBackground()”等待一个数组列表【英文标题】:How to make the AsyncTask "doInBackground()" wait for an arraylist 【发布时间】:2018-01-14 20:46:28 【问题描述】:我想在我的 android 设备上的本地 SQL DB 中保存一些对象。
如果我尝试运行该应用程序,我会在 onPostExecute() 的单元格 ArrayList 上收到 null object reference
错误。
公共类 CellApiTask 扩展 AsyncTask> 私有上下文上下文;
public CellApiTask(Context context)
this.context = context;
@Override
protected ArrayList<Cell> doInBackground(Void... params)
Fragment_Battery_Cell_Voltage cellVoltageClass = new Fragment_Battery_Cell_Voltage();
return cellVoltageClass.getCellsForDB();
@Override
protected void onPostExecute(ArrayList<Cell> cell)
CellDbHelper dbHelper = new CellDbHelper(context);
try
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
try
/* delete old db if it exists */
db.delete(CellEntryContract.CellEntry.TABLE_NAME_CELL, null, null);
catch (Exception e)
for (int i = 0; i<cell.size();i++)
values.put(CellEntryContract.CellEntry.COLUMN_NAME_CELL_NUMBER, cell.get(i).getCellNo());
values.put(CellEntryContract.CellEntry.COLUMN_NAME_CELL_DENSITY, cell.get(i).getDensity());
values.put(CellEntryContract.CellEntry.COLUMN_NAME_CELL_VOLTAGE, cell.get(i).getCellVoltage());
db.insert(CellEntryContract.CellEntry.TABLE_NAME_CELL, null, values);
Log.i(CellStorage.class.toString(),"Cells successful saved");
catch(Exception ex)
Log.e(CellStorage.class.toString(), "Could not save cells in local data storage. ", ex);
finally
if (dbHelper != null)
dbHelper.close();
片段:
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
....
amountOfCells = (((AnnualServiceActivity) getActivity()).getBatteryFromIntent().getCell().intValue());
generateGrid();
CellStorage cellStorage = new CellStorage(getContext());
cellStorage.runCellApiTasks();
return view;
....
public ArrayList<Cell> getCellsForDB()
for (int i = 0; i < amountOfCells; i++)
Cell cell = new Cell();
cell.setCellNo(i + 1);
cell.setCellVoltage(0);
cell.setDensity(0);
Log.i("öööööööööööö",cellsForDB.get(i).getCellNo()+"");
cellsForDB.add(cell);
return cellsForDB;
...
我认为在 getCellsForDB() 中准备好 ArrayList 之前完成的 doInBackground(...) 方法可能是因为我收到空对象引用错误。那么是否可以让方法等到 getCellsForDB() 中的 ArrayList 准备好?
崩溃日志:
08-07 15:43:54.388 1585-1585/frontend.datastorage.CellStorage: Could not save cells in local data storage.
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
at CellApiTask.onPostExecute(CellApiTask.java:49)
at CellApiTask.onPostExecute(CellApiTask.java:20)
at android.os.AsyncTask.finish(AsyncTask.java:660)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:677)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6692)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
08-07 15:43:54.392 1585-1585/fronius.com.serviceapp_frontend E/class fronius.com.serviceapp_frontend.datastorage.CellStorage: Could not save cells in local data storage.
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
at CellApiTask.onPostExecute(CellApiTask.java:49)
at CellApiTask.onPostExecute(CellApiTask.java:20)
at android.os.AsyncTask.finish(AsyncTask.java:660)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:677)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6692)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
【问题讨论】:
添加你的崩溃日志 你在哪里实例化了 cellsForDB? @USKMobility 我添加了错误日志。我在 Fragment onCreateView() 方法中实例化它 getCellsForDB 这个方法是另一个类 @WeSt 你在后台创建片段的新实例 oncreate() 和 oncreateview() 此时也不会调用你的所有列表..不会被实例化 【参考方案1】:您不必在这里等待任何东西,doInBackground 方法在 cellVoltageClass.getCellsForDB() 返回时完成其执行。 getCellsForDB() 似乎返回 null,因为 cellsForDB 为 null(您没有早点崩溃的唯一原因是因为 amountOfCells 为 0 并且 getCellsForDB() 内部的 for 没有循环)
【讨论】:
这听起来很正确。但是,如果首先插入 Fragment,则 amountOfCells 不为 0,它会运行。如何先完成片段的插入,然后调用 cellsForDB。我试图在 Fragment 的 onCreateView() 末尾调用 doInBackground,但它不起作用 让你的应用程序逻辑与片段生命周期事件绑定不是一个好方法,但你可以在第一次调用片段的 onResume() 时做到这一点 - 在这里你可以确定你的片段已经“插入”,现在对用户可见。以上是关于如何使 AsyncTask“doInBackground()”等待一个数组列表的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Android AsyncTask 更改活动 UI?