gpt4 book ai didi

java - Web 服务手动同步后 RecyclerView 不刷新

转载 作者:行者123 更新时间:2023-12-02 03:05:35 26 4
gpt4 key购买 nike

我遇到了手动同步 Web 服务后 RecyclerView 不刷新的问题。手动同步是通过在列表上向下滑动或点击 ActionBar 项目来触发的。手动同步使用 Volley 请求检索 JSON 格式的数据,数据被解析并保存到 SQLite 数据库表中。同步日期时间也会保存到 SQLite 数据库表中,然后显示在 fragment 的 ActionBar 副标题中。 Volley 请求通过 WorkManager OneTimeWorkRequest 启动。

问题是 RecyclerView 列表未刷新。但是,如果我随后触发另一次手动同步,则 ActionBar Subtitle 和 RecyclerView 内容中的同步数据时间将更新,但会使用之前手动同步的数据。如果我从应用程序导航到设备的主屏幕,然后导航回我的应用程序,这一点就会变得清晰,该应用程序现在显示最近手动同步的刷新数据。

我已经查看了许多有关此问题的帖子(见下文),虽然我认为我已经改进了我的代码,但是推荐的解决方案都没有解决该问题。

Recyclerview not call onCreateViewHolder RecyclerView not calling onCreateViewHolder or onBindView Recyclerview not call onCreateViewHolder RecyclerView is not refreshing

get JSON data from web and display using RecyclerView Recycler View appear blank and doesn't show SQLite data

RecyclerView onClick not working properly? Why doesn't RecyclerView have onItemClickListener()?

ListView not updating after web service Sync

查看过的其他资源: https://www.mytrendin.com/display-data-recyclerview-using-sqlitecursor-in-android/ https://medium.com/@studymongolian/updating-data-in-an-android-recyclerview-842e56adbfd8 https://www.youtube.com/watch?v=ObU-wCqoo2I https://www.youtube.com/watch?v=_0C18cbv6UE

经过几个月的努力解决这个问题,我现在向 StackOverflow 社区寻求帮助。

fragment


@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_warning_list, container, false);

mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.warning_swipe_refresh_layout);

/* Set the Refresh Listener for the Swipe gesture */
mSwipeRefreshLayout.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
SyncWarningsScheduler.oneTime();
updateUI();
}
}
);

mWarningRecyclerView = (RecyclerView) view.findViewById(R.id.warning_recycler_view);

/* Set the Toolbar to replace the default ActionBar, which has been hidden */
if (mActivity != null) {
Toolbar toolbar = (Toolbar) mActivity.findViewById(R.id.toolbar_abstract_single_fragment);
mActivity.setSupportActionBar(toolbar);

/* Set the toolbar title */
ActionBar actionbar = mActivity.getSupportActionBar();
if (actionbar != null) {
actionbar.setDisplayHomeAsUpEnabled(true);
actionbar.setTitle(getString(R.string.warning_list_fragment_toolbar_title));
}
}

updateUI();
return view;
}


@Override
public void onResume() {
super.onResume();
updateUI();
}


@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.fragment_warning_list, menu);
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.sync:
mSwipeRefreshLayout.setRefreshing(true);
SyncWarningsScheduler.oneTime();
updateUI();

return true;
case R.id.information:
/* Handle the Information Menu Item */
FragmentManager fm = getFragmentManager();
if (fm != null) {
WarningListFragmentTFBInformationDialogFragment dialog = new WarningListFragmentTFBInformationDialogFragment();
dialog.show(fm, TFB_INFO_DIALOG_TAG);
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}


private void updateUI() {
WarningList warningList = WarningList.get(mActivity);
List<Warning> warnings = warningList.getWarnings();

if (mWarningAdaptor == null) {
mWarningAdaptor = new WarningAdaptor(warnings);
mWarningRecyclerView.setLayoutManager(new LinearLayoutManager(mContext));
mWarningRecyclerView.setAdapter(mWarningAdaptor);
} else {
mWarningAdaptor.setWarnings(warnings);
mWarningAdaptor.notifyDataSetChanged();
}

/* Update the ToolBar sub title to show the latest sync datetime */
updateToolBarSubTitle();

/* If visible, turn off the Swipe Refresh Progress Circle */
if (mSwipeRefreshLayout != null && mSwipeRefreshLayout.isRefreshing()) {
mSwipeRefreshLayout.setRefreshing(false);
}
}


private void updateToolBarSubTitle() {
SyncInformationList syncInformationList = SyncInformationList.get(mContext);
Date syncDate = syncInformationList.getSyncDatetime(ORMSync.getWarningSyncTypeKey());

ActionBar actionBar = mActivity.getSupportActionBar();
if (actionBar != null) {
actionBar.setSubtitle(DatabaseUtilities.formatDateSpecial(syncDate, true));
}
}


private class WarningHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private Warning mWarning;
private TextView mIssueForTextView;
private TextView mDeclarationTextView;
private View mStatusWarningViewLeft;
private View mStatusWarningViewRight;

public WarningHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater.inflate(R.layout.list_item_warning, parent, false));
/* Handlers a user press on a Warning */
itemView.setOnClickListener(this);

mIssueForTextView = (TextView) itemView.findViewById(R.id.issueFor_textView);
mDeclarationTextView = (TextView) itemView.findViewById(R.id.declaration_textView);
mStatusWarningViewLeft = (View) itemView.findViewById(R.id.status_warning_left);
mStatusWarningViewRight = (View) itemView.findViewById(R.id.status_warning_right);
}

public void bind(Warning warning) {
mWarning = warning;
String issueForDate;

issueForDate = DatabaseUtilities.formatDateSpecial(mWarning.getIssuedFor(), "d MMM yyyy");
mIssueForTextView.setText(issueForDate);

mDeclarationTextView.setText(mWarning.getTfbDeclaration());
/* Set Declaration text colour */
if (mWarning.isTfbStatus()) {
/* If the day is a TFB set text color to Red */
mIssueForTextView.setTextColor(getResources().getColor(R.color.red));
mDeclarationTextView.setTextColor(getResources().getColor(R.color.red));
}

/* Set left and right status warning colour based on TFB status */
mStatusWarningViewLeft.setBackgroundResource(mWarning.setStatusWarningColor());
mStatusWarningViewRight.setBackgroundResource(mWarning.setStatusWarningColor());
}

@Override
public void onClick(View v) {
/* Process onClick */
Intent intent = WarningPagerActivity.newIntent(mActivity, mWarning.getUID());
startActivity(intent);
}
}


private class WarningAdaptor extends RecyclerView.Adapter<WarningHolder> {
private List<Warning> mWarnings;

public WarningAdaptor(List<Warning> warnings) {
mWarnings = warnings;
}

@NonNull
@Override
public WarningHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(mActivity);
return new WarningHolder(layoutInflater, parent);
}

@Override
public void onBindViewHolder(@NonNull WarningHolder holder, int position) {
/* Bind data */
Warning warning = mWarnings.get(position);
holder.bind(warning);
}

@Override
public int getItemCount() {
return mWarnings.size();
}

public void setWarnings(List<Warning> warnings) {
mWarnings.clear();
mWarnings = warnings;
}

public List<Warning> getWarnings() {
return mWarnings;
}
}
}

WorkManager oneTimeWorkRequest 调度程序

public class SyncWarningsScheduler {
private static final String TAG = "SyncWarningsScheduler";
private static final String ONE_TIME_WORK_REQUEST = "OneTime";
private static final String ONE_TIME_WORK_REQUEST_TAG = TAG + ONE_TIME_WORK_REQUEST;
private static final String ONE_TIME_WORK_REQUEST_TAG_UNIQUE = ONE_TIME_WORK_REQUEST_TAG + "Unique";


/* Getters and Setters */
public static String getOneTimeWorkRequestTagUnique() {
return ONE_TIME_WORK_REQUEST_TAG_UNIQUE;
}

public static void oneTime() {
WorkManager workManager = WorkManager.getInstance();

/* Create a Constraints object that defines when and how the task should run */
Constraints constraints = new Constraints.Builder()
.setRequiresCharging(false)
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();

/* Build the Input Data to pass to the Worker */
Data inputData = new Data.Builder()
.putString(SyncWarningsWorker.getWorkRequestTypeKey(), ONE_TIME_WORK_REQUEST)
.build();

/* Build the One Time Work Request */
OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(SyncWarningsWorker.class)
.setConstraints(constraints)
/* Sets the input data for the ListenableWorker */
.setInputData(inputData)
.addTag(ONE_TIME_WORK_REQUEST_TAG)
.build();

workManager.enqueueUniqueWork(ONE_TIME_WORK_REQUEST_TAG_UNIQUE, ExistingWorkPolicy.REPLACE, oneTimeWorkRequest);
}
}

WorkManager 工作人员

public class SyncWarningsWorker extends Worker {
private static final String TAG = "SyncWarningsWorker";
private Context mContext;
private SQLiteDatabase mDatabase;
private WarningList mWarningList;

private static final String WORK_REQUEST_TYPE_KEY = "warningworkrequesttype";
private static final String SYNC_DATE_TIME_KEY = "warningsyncdatetime";

public SyncWarningsWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);

/* Set the Context which must be the Application Context */
mContext = context;

mDatabase = IncidentsDatabaseHelper.get(context).getWritableDatabase();
/* Get a refer to the WarningList Singleton */
mWarningList = WarningList.get(context);
}

/* Getters and Setters */
public static String getWorkRequestTypeKey() {
return WORK_REQUEST_TYPE_KEY;
}

public static String getSyncDateTimeKey() {
return SYNC_DATE_TIME_KEY;
}


@NonNull
@Override
public Result doWork() {
/* Read passed-in argument(s) */
String workRequestType = getInputData().getString(WORK_REQUEST_TYPE_KEY);
LogUtilities.info(TAG, "doWork() - Processing EMV Warnings Work Request Type: " + workRequestType);

try {
downloadWarnings();

Date now = new Date();
long nowMilliSeconds = now.getTime();
now.setTime(nowMilliSeconds);

/* Update the WarningSyncType in SyncInformationList with the Warnings Sync Datetime */
SyncInformationList syncInformationList = SyncInformationList.get(mContext);
syncInformationList.updateSyncDatetime(ORMSync.getWarningSyncTypeKey(), now);

Data syncDateTime = new Data.Builder()
.putLong(SYNC_DATE_TIME_KEY, nowMilliSeconds)
.build();

return Result.success(syncDateTime);
} catch (Exception e){
LogUtilities.error(TAG, "doWork() - Can't download EMV Warnings data.\n\n" + e.toString());
return Result.failure();
}
}

private void downloadWarnings() {
VolleyRequestQueue volleyRequestQueue;

StringRequest request = new StringRequest(Request.Method.GET, JSONWarningsSchema.getTfbFdrJsonEndPoint(), onPostsLoaded, onPostsError);

volleyRequestQueue = VolleyRequestQueue.get(mContext);

volleyRequestQueue.addToVolleyRequestQueue(request);
}

private final Response.Listener<String> onPostsLoaded = new Response.Listener<String>() {
ContentValues contentvalues;
String noData = "NO DATA";

@Override
public void onResponse(String response) {
/* Delete all the Warning records from the SQLite table */
mWarningList.deleteAllWarnings();

try {
JSONObject jsonBody = new JSONObject(response);
/* Within jsonBody is one nested JSON Array */
JSONArray jsonArrayResults = jsonBody.getJSONArray(JSONWarningsSchema.getJsonRootArrayName());

for (int i = 0; i < jsonArrayResults.length(); i++) {
/*
* Within jsonArrayResults are 10 sometimes 9 JSON Objects, the first 5 Objects are for TFB declarations and
* the last 5 (4) Objects are for FDR declarations.
*/
JSONObject warningMetadata = jsonArrayResults.getJSONObject(i);

if (i < 5) {
/*
* The first 5 Objects are for Today and the next 4 days worth of TFB declarations. The TFB declaration in these Objects are
* used to INSERT new records into the warnings table using the issueFor date as the Alternate Primary Key.
* The FDR declarations for each day are defaulted to "NO DATA" to cater for the sometimes missing FDR data on the 5th day, this is
* to avoid null pointer errors when displaying the data in fragment_warning.
*/
Warning warning = new Warning();

String issueForDate = warningMetadata.getString(JSONWarningsSchema.Keys.getIssueFor());
warning.setIssuedFor(JSONUtilities.stringToDate(issueForDate, JSONWarningsSchema.getJsonIssueForDateFormat()));

String status = warningMetadata.getString(JSONWarningsSchema.Keys.getStatus());
warning.setTfbStatus(JSONUtilities.stringToBoolean(status));

warning.setTfbDeclaration(warningMetadata.getString(JSONWarningsSchema.Keys.getDeclaration()));

/*
* Within the warningMetadata JSONObject is a JSONArray called declareList. Need to get the Array and
* iterate through the Array to extract the TFB warning for each District for this day.
* We know the exact number of JSONObjects in the declareList Array (ie an Object for each District).
*/
JSONArray jsonArrayTFBDeclareList = warningMetadata.getJSONArray(JSONWarningsSchema.getJsonDeclareListArrayName());

/* Iterate through the TFB declareList Array */
for (int j = 0; j < jsonArrayTFBDeclareList.length(); j++) {
/* Get the JSON Object within the jsonArrayDeclareList Array */
JSONObject declareListMetadata = jsonArrayTFBDeclareList.getJSONObject(j);

/* Get the name and status pairs from the declareListMetadata Object */
String name = declareListMetadata.getString(JSONWarningsSchema.Keys.getDeclareListName());
String declareListStatus = declareListMetadata.getString(JSONWarningsSchema.Keys.getDeclareListStatus());

switch (name) {
case "Mallee":
warning.setTfbMallee(declareListStatus);
warning.setFdrMallee(noData);
break;
case "Wimmera":
warning.setTfbWimmera(declareListStatus);
warning.setFdrWimmera(noData);
break;
case "South West":
warning.setTfbSouthWest(declareListStatus);
warning.setFdrSouthWest(noData);
break;
case "Northern Country":
warning.setTfbNorthernCountry(declareListStatus);
warning.setFdrNorthernCountry(noData);
break;
case "North Central":
warning.setTfbNorthCentral(declareListStatus);
warning.setFdrNorthCentral(noData);
break;
case "Central":
warning.setTfbCentral(declareListStatus);
warning.setFdrCentral(noData);
break;
case "North East":
warning.setTfbNorthEast(declareListStatus);
warning.setFdrNorthEast(noData);
break;
case "West and South Gippsland":
warning.setTfbWestAndSouthGippsland(declareListStatus);
warning.setFdrWestAndSouthGippsland(noData);
break;
case "East Gippsland":
warning.setTfbEastGippsland(declareListStatus);
warning.setFdrEastGippsland(noData);
break;
default:
break;
}
}

contentvalues = ContentValueUtilities.getWarningListContentValues(warning, true);

mDatabase.beginTransaction();
try {
mDatabase.insert(ORMWarnings.getTableName(), null, contentvalues);
mDatabase.setTransactionSuccessful();
} catch (SQLiteException e) {
LogUtilities.error(TAG, "onPostsLoaded > onResponse - ERROR Inserting record into the '" + ORMWarnings.getTableName() + "' Table.\n\n" + e.toString());
} finally {
mDatabase.endTransaction();
}
} else {
/*
* The last 5 or sometimes 4 Objects are for Today and the next 4 days worth of FDR declarations. The FDR declarations
* in these Objects are used to UPDATE FDR attributes in the warnings table using the issueFor date to find the existing warnings
* record.
*/
String issueForFDR = warningMetadata.getString(JSONWarningsSchema.Keys.getIssueFor());
/* Ensure the retrieved issueFor date string is converted consistently */
Date issueForFDRDate = JSONUtilities.stringToDate(issueForFDR, JSONWarningsSchema.getJsonIssueForDateFormat());

/* Find the record in the warnings table by using the issueForFDRDate date. */
Warning warningExists = mWarningList.getWarning(issueForFDRDate);

/* Make sure a warning record has been returned */
if (warningExists != null) {
String issueAtDate = warningMetadata.getString(JSONWarningsSchema.Keys.getIssueAt());
warningExists.setFdrIssuedAt(JSONUtilities.stringToDate(issueAtDate, JSONWarningsSchema.getJsonIssueAtDateFormat()));

/*
* Within the warningMetadata JSONObject is a JSONArray called declareList. Need to get the Array and
* iterate through the Array to extract the FDR warning for each District for this day.
* We know the exact number of JSONObjects in the declareList Array (ie an Object for each District).
*/
JSONArray jsonArrayFDRDeclareList = warningMetadata.getJSONArray(JSONWarningsSchema.getJsonDeclareListArrayName());

/* Iterate through the FDR declareList Array */
for (int z = 0; z < jsonArrayFDRDeclareList.length(); z++) {
/* Get the JSON Object within the jsonArrayFDRDeclareList Array */
JSONObject declareListMetadataFDR = jsonArrayFDRDeclareList.getJSONObject(z);

/* Get the name and status pairs from the declareListMetadataFDR Object */
String nameFDR = declareListMetadataFDR.getString(JSONWarningsSchema.Keys.getDeclareListName());
String declareListStatusFDR = declareListMetadataFDR.getString(JSONWarningsSchema.Keys.getDeclareListStatus());

switch (nameFDR) {
case "Mallee":
warningExists.setFdrMallee(declareListStatusFDR);
break;
case "Wimmera":
warningExists.setFdrWimmera(declareListStatusFDR);
break;
case "South West":
warningExists.setFdrSouthWest(declareListStatusFDR);
break;
case "Northern Country":
warningExists.setFdrNorthernCountry(declareListStatusFDR);
break;
case "North Central":
warningExists.setFdrNorthCentral(declareListStatusFDR);
break;
case "Central":
warningExists.setFdrCentral(declareListStatusFDR);
break;
case "North East":
warningExists.setFdrNorthEast(declareListStatusFDR);
break;
case "West and South Gippsland":
warningExists.setFdrWestAndSouthGippsland(declareListStatusFDR);
break;
case "East Gippsland":
warningExists.setFdrEastGippsland(declareListStatusFDR);
break;
default:
break;
}
}

contentvalues = ContentValueUtilities.getWarningListContentValues(warningExists, false);

mDatabase.beginTransaction();
try {
mDatabase.update(ORMWarnings.getTableName(), contentvalues, ORMWarnings.getUUIDColumn() + " = ?", new String[] {warningExists.getUID().toString()});
mDatabase.setTransactionSuccessful();
} catch (SQLiteException e) {
LogUtilities.error(TAG, "onPostsLoaded > onResponse - ERROR Updating record in the '" + ORMWarnings.getTableName() + "' Table.\n\n" + e.toString());
} finally {
mDatabase.endTransaction();
}
} else {
/* Something went wrong can't find warning record using the issueForFDRDate date */
LogUtilities.wtf(TAG, "onPostsLoaded > onResponse - " + issueForFDRDate.toString() + " warning record not found.\n\n");
}
}
}
} catch (JSONException e) {
LogUtilities.error(TAG, "onPostsLoaded > onResponse - Failed to Parse JSON body.\n\n" + e.toString());
}
}
};


private final Response.ErrorListener onPostsError = new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
LogUtilities.error(TAG, "onPostsError > onErrorResponse - Failed to download JSON body.\n\n" + error.toString());
}
};
}

最佳答案

在您的适配器中使用它

 public void setWarnings(List<Warning> warnings) {
mWarnings.clear();
mWarnings = warnings;
notifyDataSetChanged();

}

关于java - Web 服务手动同步后 RecyclerView 不刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57024454/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com