如何在 android 中通过 AsyncTask return 多个列表 <String>?
How to return multiple List<String> via AsyncTask in android?
我创建了一个 AsynTaskInsideActivity
class,它在 MainActivity
中扩展 AsyncTask<Void, Void, List<String>>
作为内部 class。我正在使用此 AsynTaskInsideActivity
从 location
table 获取所有记录。此位置 table 具有以下列:
- location_id
- 国家
- 状态
- zip_code
我想从每个单独的列中获取记录。因此,为了存储每个单独列的每条记录,我创建了四个 List
类型的数组(即每个列一个)并成功地将检索到的 Cursor
数据存储在每个数组中。现在,问题是我需要 return 每一列的记录。因此,具体来说,我如何 return 来自一个 AsyncTask
class 的那四个单独的 List
类型数组。目前,我只 returning 列表类型数组,即 locationId
,它具有我从位置 table 的 location_id
列中获取的所有位置 ID。
问题:
- 如何从单个
AsyncTask
class 中 return 多个列表数组项?毕竟当我们查询数据库时,有时我们需要来自单个 table 的多个列的记录来处理进一步的操作。
- 有没有更好的方法可以用来解决这个问题?或者我不得不相信有些事情真的是不可能的。
这是我的 AsyncTask
class 的样子:
public class AsyncTaskInsideActivity extends AsyncTask<Void, Void, List<String>> {
private static final String CLASS_TAG = AsyncTaskInsideActivity.class.getSimpleName();
@Override
protected List<String> doInBackground(Void... params) {
Log.v(CLASS_TAG, "AsyncTaskInsideActivity started successfully....");
SoCalledDbHelper soCalledDbHelper = new SoCalledDbHelper
(getBaseContext());
//key-value pairs for inserting data into the table
ContentValues soCalledValues = new ContentValues();
soCalledValues.put(SoCalledContract.LocationTable.COLUMN_CITY_NAME, "Kim Kardishian");
soCalledValues.put(SoCalledContract.LocationTable.COLUMN_STATE, "No Ass Holes");
soCalledValues.put(SoCalledContract.LocationTable.COLUMN_ZIP_CODE, 007);
//insert location data
soCalledDbHelper.addLocationData(soCalledValues);
//For storing the cursor data which will be retrieved by the read query.
Cursor locationDataCursor;
//Query for all the data in the location table
locationDataCursor = soCalledDbHelper.getAllLocationData(null, null, null, null);
List<String> sCLocationId = new ArrayList<String>();
List<String> sCCityName = new ArrayList<String>();
List<String> sCState = new ArrayList<String>();
List<String> sCZipCode = new ArrayList<String>();
if (locationDataCursor.getCount() > 0) {
//Reset the cursor location
locationDataCursor.moveToPosition(-1);
while (locationDataCursor.moveToNext()) {
//Extracting data from the location cursor
sCLocationId.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("_id")));
sCCityName.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("city_name")));
sCState.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("state")));
sCZipCode.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("zip_code")));
}
Log.i(CLASS_TAG, "Success: Cursor has data! #Total Records: " +
locationDataCursor.getCount());
for (String locationIds : sCLocationId) {
Log.i(CLASS_TAG, "Location Id: + " + locationIds);
}
for (String cityNamez : sCCityName) {
Log.i(CLASS_TAG, "City Names: + " + cityNamez);
}
for (String statesNames : sCState) {
Log.i(CLASS_TAG, "State Names: + " + statesNames);
}
for (String zipCodes : sCZipCode) {
Log.i(CLASS_TAG, "Zip Codes: + " + zipCodes);
}
} else {
Log.w(CLASS_TAG, "Error: Cursor is empty! #Total Records: " +
locationDataCursor.getCount());
}
locationDataCursor.close();
soCalledDbHelper.close();
Log.v(CLASS_TAG, "AsyncTaskDbHelper ended successfully....");
return sCLocationId;
}
}
您可以 return 从 AsyncTask<Void, Void, List<List<String>>
扩展您的 AsyncTask 并完成它,但这不是最好的方法。
更好的方法是扩展 AsyncTask<Void, Void, List<Location>>
,其中 Location 定义为:
public class Location
{
private String location_id;
private String country;
private String state;
private String zip_code;
// Constructors, getters and setters go here. Your IDE should be able to generate them.
// You can also override the toString method to format the output better
}
你的循环看起来像这样:
List<Location> locations_list = new ArrayList<Location>();
if (locationDataCursor.moveToFirst()) {// Moves to first if cursor is not empty
do{
Location location = new Location();
//Extracting data from the location cursor
location.setID(locationDataCursor.getString
(locationDataCursor.getColumnIndex("_id")));
location.setCity(locationDataCursor.getString
(locationDataCursor.getColumnIndex("city_name")));
location.setState(locationDataCursor.getString
(locationDataCursor.getColumnIndex("state")));
location.setZip(locationDataCursor.getString
(locationDataCursor.getColumnIndex("zip_code")));
// Add location to the list
locations_list.add(location)
}while (locationDataCursor.moveToNext())
Log.i(CLASS_TAG, "Success: Cursor has data! #Total Records: " +
locationDataCursor.getCount());
for (Location l : locations_list) {
Log.i(CLASS_TAG, "Location: " + l.toString());
}
} else {
Log.w(CLASS_TAG, "Error: Cursor is empty!"
}
// Close any open DB objects
locationDataCursor.close();
soCalledDbHelper.close();
Log.v(CLASS_TAG, "AsyncTaskDbHelper ended successfully....");
// Return the list of locations
return locations_list;
好吧,在通过互联网研究这个问题的解决方案并投入几个小时将单个 AsyncTask 设置为 return 多个值之后,我想出了一个嵌套 List
数组的解决方案即 List<List<String>>
原创作品:
@Simon:谁给了我一个指示(或暗示)我如何更新我的 AsyncTask
以获得完成的工作,事实证明这真的很有帮助。
@VERT9x:感谢您付出努力并用不同的方法完成工作。
解法:
public class AsyncTaskInsideActivity extends AsyncTask<Void, Void, List<List<String>>> {
private static final String CLASS_TAG = AsyncTaskInsideActivity.class.getSimpleName();
@Override
protected List<String> doInBackground(Void... params) {
Log.v(CLASS_TAG, "AsyncTaskInsideActivity started successfully....");
SoCalledDbHelper soCalledDbHelper = new SoCalledDbHelper
(getBaseContext());
//key-value pairs for inserting data into the table
ContentValues soCalledValues = new ContentValues();
soCalledValues.put(SoCalledContract.LocationTable.COLUMN_CITY_NAME, "Kim Kardishian");
soCalledValues.put(SoCalledContract.LocationTable.COLUMN_STATE, "No Ass Holes");
soCalledValues.put(SoCalledContract.LocationTable.COLUMN_ZIP_CODE, 007);
//insert location data
soCalledDbHelper.addLocationData(soCalledValues);
//For storing the cursor data which will be retrieved by the read query.
Cursor locationDataCursor;
//Query for all the data in the location table
locationDataCursor = soCalledDbHelper.getAllLocationData(null, null, null, null);
List<String> sCLocationId = new ArrayList<String>();
List<String> sCCityName = new ArrayList<String>();
List<String> sCState = new ArrayList<String>();
List<String> sCZipCode = new ArrayList<String>();
if (locationDataCursor.getCount() > 0) {
//Reset the cursor location
locationDataCursor.moveToPosition(-1);
while (locationDataCursor.moveToNext()) {
//Extracting data from the location cursor
sCLocationId.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("_id")));
sCCityName.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("city_name")));
sCState.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("state")));
sCZipCode.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("zip_code")));
}
Log.i(CLASS_TAG, "Success: Cursor has data! #Total Records: " +
locationDataCursor.getCount());
for (String locationIds : sCLocationId) {
Log.i(CLASS_TAG, "Location Id: + " + locationIds);
}
for (String cityNamez : sCCityName) {
Log.i(CLASS_TAG, "City Names: + " + cityNamez);
}
for (String statesNames : sCState) {
Log.i(CLASS_TAG, "State Names: + " + statesNames);
}
for (String zipCodes : sCZipCode) {
Log.i(CLASS_TAG, "Zip Codes: + " + zipCodes);
}
} else {
Log.w(CLASS_TAG, "Error: Cursor is empty! #Total Records: " +
locationDataCursor.getCount());
}
locationDataCursor.close();
soCalledDbHelper.close();
//Creating a List that can store List(s) within it.
//List of Lists String
List<List<String>> arrayOfLists = new ArrayList<List<String>>();
//Adding those Lists that was used to store each column records
arrayOfLists.add(sCLocationId);
arrayOfLists.add(sCCityName);
arrayOfLists.add(sCState);
arrayOfLists.add(sCZipCode);
//Start iterating over the parent arrayOfLists List
for(int i = 0; i < arrayOfLists.size(); i++) {
//Print each arrayOfLists data item it contains
Log.v(CLASS_TAG, "Parent List: " + arrayOfLists.get(i).toString());
//Start iterating over child of arrayOfLists List
for(int j = 0; j < arrayOfLists.get(i).size(); j++) {
//Print each arrayOfLists CHILD data item it contains
Log.v(CLASS_TAG, "Child List: " + arrayOfLists.get(i).get(j).toString());
}
}
//Size of the arrayOfLists
Log.v(CLASS_TAG, "Parent List Size: " + Integer.toString(arrayOfLists.size()));
//Size of the arrayOfLists child container
Log.v(CLASS_TAG, "Child List Size: " + Integer.toString(arrayOfLists.get(1).size()));
Log.v(CLASS_TAG, "AsyncTaskDbHelper ended successfully....");
return arrayOfLists;
}
我所做的更改:
- 将 AsyncTask class 和 doInBackground() return 类型的第 3 个参数更改为
List<List<String>>
,因此它可以 return 多个值。
解决办法见下面这两行:
locationDataCursor.close();
soCalledHelper.close();
我创建了一个 AsynTaskInsideActivity
class,它在 MainActivity
中扩展 AsyncTask<Void, Void, List<String>>
作为内部 class。我正在使用此 AsynTaskInsideActivity
从 location
table 获取所有记录。此位置 table 具有以下列:
- location_id
- 国家
- 状态
- zip_code
我想从每个单独的列中获取记录。因此,为了存储每个单独列的每条记录,我创建了四个 List
类型的数组(即每个列一个)并成功地将检索到的 Cursor
数据存储在每个数组中。现在,问题是我需要 return 每一列的记录。因此,具体来说,我如何 return 来自一个 AsyncTask
class 的那四个单独的 List
类型数组。目前,我只 returning 列表类型数组,即 locationId
,它具有我从位置 table 的 location_id
列中获取的所有位置 ID。
问题:
- 如何从单个
AsyncTask
class 中 return 多个列表数组项?毕竟当我们查询数据库时,有时我们需要来自单个 table 的多个列的记录来处理进一步的操作。 - 有没有更好的方法可以用来解决这个问题?或者我不得不相信有些事情真的是不可能的。
这是我的 AsyncTask
class 的样子:
public class AsyncTaskInsideActivity extends AsyncTask<Void, Void, List<String>> {
private static final String CLASS_TAG = AsyncTaskInsideActivity.class.getSimpleName();
@Override
protected List<String> doInBackground(Void... params) {
Log.v(CLASS_TAG, "AsyncTaskInsideActivity started successfully....");
SoCalledDbHelper soCalledDbHelper = new SoCalledDbHelper
(getBaseContext());
//key-value pairs for inserting data into the table
ContentValues soCalledValues = new ContentValues();
soCalledValues.put(SoCalledContract.LocationTable.COLUMN_CITY_NAME, "Kim Kardishian");
soCalledValues.put(SoCalledContract.LocationTable.COLUMN_STATE, "No Ass Holes");
soCalledValues.put(SoCalledContract.LocationTable.COLUMN_ZIP_CODE, 007);
//insert location data
soCalledDbHelper.addLocationData(soCalledValues);
//For storing the cursor data which will be retrieved by the read query.
Cursor locationDataCursor;
//Query for all the data in the location table
locationDataCursor = soCalledDbHelper.getAllLocationData(null, null, null, null);
List<String> sCLocationId = new ArrayList<String>();
List<String> sCCityName = new ArrayList<String>();
List<String> sCState = new ArrayList<String>();
List<String> sCZipCode = new ArrayList<String>();
if (locationDataCursor.getCount() > 0) {
//Reset the cursor location
locationDataCursor.moveToPosition(-1);
while (locationDataCursor.moveToNext()) {
//Extracting data from the location cursor
sCLocationId.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("_id")));
sCCityName.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("city_name")));
sCState.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("state")));
sCZipCode.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("zip_code")));
}
Log.i(CLASS_TAG, "Success: Cursor has data! #Total Records: " +
locationDataCursor.getCount());
for (String locationIds : sCLocationId) {
Log.i(CLASS_TAG, "Location Id: + " + locationIds);
}
for (String cityNamez : sCCityName) {
Log.i(CLASS_TAG, "City Names: + " + cityNamez);
}
for (String statesNames : sCState) {
Log.i(CLASS_TAG, "State Names: + " + statesNames);
}
for (String zipCodes : sCZipCode) {
Log.i(CLASS_TAG, "Zip Codes: + " + zipCodes);
}
} else {
Log.w(CLASS_TAG, "Error: Cursor is empty! #Total Records: " +
locationDataCursor.getCount());
}
locationDataCursor.close();
soCalledDbHelper.close();
Log.v(CLASS_TAG, "AsyncTaskDbHelper ended successfully....");
return sCLocationId;
}
}
您可以 return 从 AsyncTask<Void, Void, List<List<String>>
扩展您的 AsyncTask 并完成它,但这不是最好的方法。
更好的方法是扩展 AsyncTask<Void, Void, List<Location>>
,其中 Location 定义为:
public class Location
{
private String location_id;
private String country;
private String state;
private String zip_code;
// Constructors, getters and setters go here. Your IDE should be able to generate them.
// You can also override the toString method to format the output better
}
你的循环看起来像这样:
List<Location> locations_list = new ArrayList<Location>();
if (locationDataCursor.moveToFirst()) {// Moves to first if cursor is not empty
do{
Location location = new Location();
//Extracting data from the location cursor
location.setID(locationDataCursor.getString
(locationDataCursor.getColumnIndex("_id")));
location.setCity(locationDataCursor.getString
(locationDataCursor.getColumnIndex("city_name")));
location.setState(locationDataCursor.getString
(locationDataCursor.getColumnIndex("state")));
location.setZip(locationDataCursor.getString
(locationDataCursor.getColumnIndex("zip_code")));
// Add location to the list
locations_list.add(location)
}while (locationDataCursor.moveToNext())
Log.i(CLASS_TAG, "Success: Cursor has data! #Total Records: " +
locationDataCursor.getCount());
for (Location l : locations_list) {
Log.i(CLASS_TAG, "Location: " + l.toString());
}
} else {
Log.w(CLASS_TAG, "Error: Cursor is empty!"
}
// Close any open DB objects
locationDataCursor.close();
soCalledDbHelper.close();
Log.v(CLASS_TAG, "AsyncTaskDbHelper ended successfully....");
// Return the list of locations
return locations_list;
好吧,在通过互联网研究这个问题的解决方案并投入几个小时将单个 AsyncTask 设置为 return 多个值之后,我想出了一个嵌套 List
数组的解决方案即 List<List<String>>
原创作品:
@Simon:谁给了我一个指示(或暗示)我如何更新我的 AsyncTask
以获得完成的工作,事实证明这真的很有帮助。
@VERT9x:感谢您付出努力并用不同的方法完成工作。
解法:
public class AsyncTaskInsideActivity extends AsyncTask<Void, Void, List<List<String>>> {
private static final String CLASS_TAG = AsyncTaskInsideActivity.class.getSimpleName();
@Override
protected List<String> doInBackground(Void... params) {
Log.v(CLASS_TAG, "AsyncTaskInsideActivity started successfully....");
SoCalledDbHelper soCalledDbHelper = new SoCalledDbHelper
(getBaseContext());
//key-value pairs for inserting data into the table
ContentValues soCalledValues = new ContentValues();
soCalledValues.put(SoCalledContract.LocationTable.COLUMN_CITY_NAME, "Kim Kardishian");
soCalledValues.put(SoCalledContract.LocationTable.COLUMN_STATE, "No Ass Holes");
soCalledValues.put(SoCalledContract.LocationTable.COLUMN_ZIP_CODE, 007);
//insert location data
soCalledDbHelper.addLocationData(soCalledValues);
//For storing the cursor data which will be retrieved by the read query.
Cursor locationDataCursor;
//Query for all the data in the location table
locationDataCursor = soCalledDbHelper.getAllLocationData(null, null, null, null);
List<String> sCLocationId = new ArrayList<String>();
List<String> sCCityName = new ArrayList<String>();
List<String> sCState = new ArrayList<String>();
List<String> sCZipCode = new ArrayList<String>();
if (locationDataCursor.getCount() > 0) {
//Reset the cursor location
locationDataCursor.moveToPosition(-1);
while (locationDataCursor.moveToNext()) {
//Extracting data from the location cursor
sCLocationId.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("_id")));
sCCityName.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("city_name")));
sCState.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("state")));
sCZipCode.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("zip_code")));
}
Log.i(CLASS_TAG, "Success: Cursor has data! #Total Records: " +
locationDataCursor.getCount());
for (String locationIds : sCLocationId) {
Log.i(CLASS_TAG, "Location Id: + " + locationIds);
}
for (String cityNamez : sCCityName) {
Log.i(CLASS_TAG, "City Names: + " + cityNamez);
}
for (String statesNames : sCState) {
Log.i(CLASS_TAG, "State Names: + " + statesNames);
}
for (String zipCodes : sCZipCode) {
Log.i(CLASS_TAG, "Zip Codes: + " + zipCodes);
}
} else {
Log.w(CLASS_TAG, "Error: Cursor is empty! #Total Records: " +
locationDataCursor.getCount());
}
locationDataCursor.close();
soCalledDbHelper.close();
//Creating a List that can store List(s) within it.
//List of Lists String
List<List<String>> arrayOfLists = new ArrayList<List<String>>();
//Adding those Lists that was used to store each column records
arrayOfLists.add(sCLocationId);
arrayOfLists.add(sCCityName);
arrayOfLists.add(sCState);
arrayOfLists.add(sCZipCode);
//Start iterating over the parent arrayOfLists List
for(int i = 0; i < arrayOfLists.size(); i++) {
//Print each arrayOfLists data item it contains
Log.v(CLASS_TAG, "Parent List: " + arrayOfLists.get(i).toString());
//Start iterating over child of arrayOfLists List
for(int j = 0; j < arrayOfLists.get(i).size(); j++) {
//Print each arrayOfLists CHILD data item it contains
Log.v(CLASS_TAG, "Child List: " + arrayOfLists.get(i).get(j).toString());
}
}
//Size of the arrayOfLists
Log.v(CLASS_TAG, "Parent List Size: " + Integer.toString(arrayOfLists.size()));
//Size of the arrayOfLists child container
Log.v(CLASS_TAG, "Child List Size: " + Integer.toString(arrayOfLists.get(1).size()));
Log.v(CLASS_TAG, "AsyncTaskDbHelper ended successfully....");
return arrayOfLists;
}
我所做的更改:
- 将 AsyncTask class 和 doInBackground() return 类型的第 3 个参数更改为
List<List<String>>
,因此它可以 return 多个值。 解决办法见下面这两行:
locationDataCursor.close();
soCalledHelper.close();