共享首选项编辑器需要花费大量时间来提交更改

Posted

技术标签:

【中文标题】共享首选项编辑器需要花费大量时间来提交更改【英文标题】:shared preference editor takes much time to commit changes 【发布时间】:2021-12-30 15:06:07 【问题描述】:

我正在使用 Firebase 身份验证使用电话号码注册用户,并将该用户与他提供的 emailpassword 链接,如果身份验证成功,电子邮件和密码应保存在 SharedPreferences 和那么应用应该转到地图活动,否则会显示一条 toast 消息。

当地图活动启动时,它首先检查共享首选项中的一些值,如果这些值存在,地图就会显示出来,否则,应该启动另一个活动。

此过程运行良好,但问题是地图活动在共享首选项提交更改之前启动,结果地图活动将启动另一个活动,因为它没有找到应该从中保存的值注册活动。

地图活动是应用程序的起点,如果您完成了注册过程并再次重新启动应用程序,地图活动将检查这些值,然后显示地图,这就是让我说提交变化非常缓慢。

所以问题是如何确保共享偏好在移动到地图活动之前提交更改,因为地图活动将在显示地图之前检查它们

signInButton.setOnClickListener(v -> 
        if (validateFields())
            if (checkInternet())
                makeHttpRequest();
                firebaseSignUp();
            
    );

public boolean validateFields() 
    email = emailEditText.getText().toString().trim();
    password = passwordEditText.getText().toString().trim();
    nurseID = nurseIDEditText.getText().toString().trim();
    if (TextUtils.isEmpty(email)) 
        emailEditText.setError(getResources().getString(R.string.empty_field));
        emailEditText.requestFocus();
        return false;
    
    else if (TextUtils.isEmpty(password)) 
        passwordEditText.setError(getResources().getString(R.string.empty_field));
        passwordEditText.requestFocus();
        return false;
    
    else if (TextUtils.isEmpty(nurseID)) 
        nurseIDEditText.setError(getResources().getString(R.string.empty_field));
        nurseIDEditText.requestFocus();
        return false;
    
    else
        return true;


public boolean checkInternet() 
    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
    try 
        if (networkInfo != null && networkInfo.isConnected())
            return true;
        else
            Toast.makeText(this, R.string.check_connection, Toast.LENGTH_LONG).show();
     catch (NullPointerException e) 
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
    
    return false;


public void makeHttpRequest() 
    StringRequest stringRequest = new StringRequest(Request.Method.POST, NewNurseActivity.url,
            response -> 
                if (parsehtml(response)) 
                    progressBar.setVisibility(View.GONE);
                
                else 
                    progressBar.setVisibility(View.GONE);
                    notAMemberTextView.setVisibility(View.VISIBLE);
                    notAMemberTextView.setText(R.string.you_are_not_a_member);
                
            , error -> 
        parseHtml("response"); //remove this line when app comes to live
        linearLayout.setVisibility(View.GONE);
        notAMemberTextView.setVisibility(View.VISIBLE);
        notAMemberTextView.setText(R.string.unexpected_response_code);
        progressBar.setVisibility(View.GONE);
    ) 
        @Override
        protected Map<String, String> getParams() 
            Map params = new HashMap();
            params.put("member_code", nurseID);
            return params;
        
    ;
    int socketTimeOut = 10000;
    RetryPolicy retryPolicy = new DefaultRetryPolicy(socketTimeOut,
            0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
    stringRequest.setRetryPolicy(retryPolicy);
    RequestQueue queue = Volley.newRequestQueue(this);
    queue.add(stringRequest);


public boolean parseHtml(String response) 
        String nurseName = "ahmed";
        editor.putString("name", nurseName);
        editor.putString("nurseId", nurseID);
        editor.commit();
        return true;


public void firebaseSignUp() 
    AuthCredential credential = EmailAuthProvider.getCredential(email, password);
    try 
        Objects.requireNonNull(firebaseAuth.getCurrentUser()).linkWithCredential(credential).
                addOnSuccessListener(authResult -> 
                    editor.putString("email", email);
                    editor.putString("password", password);
                    editor.apply(); //here I tried editor.commit() but also didn't work 
                    startActivity(new Intent(NewNurseActivity.this, MapsActivity.class));
                    finish();
                ).addOnFailureListener(e -> 
            Log.e("sign_in_error", e.getMessage());
            Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
        );
    
    catch (NullPointerException ignored)

这就是我检查我的价值观的方式:

nurseId = PreferenceManager.getDefaultSharedPreferences(getBaseContext()).getString("nurseId", "");
    name = PreferenceManager.getDefaultSharedPreferences(getBaseContext()).getString("name", "");
    email = PreferenceManager.getDefaultSharedPreferences(getBaseContext()).getString("email", "");
    password = PreferenceManager.getDefaultSharedPreferences(getBaseContext()).getString("password", "");
    if (name.equals("") || nurseId.equals("") || email.equals("") || password.equals("")) 

        startActivity(new Intent(this, WelcomeActivity.class));
        finish();
    

【问题讨论】:

如果 MapsActivity 是起点,您在哪里进行 firebase 注册? 如果您确定 sharedPreferences 会在开始新活动后保存您的数据,您可以将 apply 替换为 commit。提交返回布尔值,指示您是否成功保存了数据。此时您可以使用常规 if(isMyDataSaved) goMapsActivity else anotherActivity 解决您的问题。 editor.commit() 将立即写入,但 editor.apply() 也会立即将值保存在 SharedPreferences 内存存储中,即使磁盘写入延迟也是如此。几乎可以肯定您的问题出在其他地方(关于地图活动如何检索值,或者在两个活动之间使用不同的共享首选项或其他内容)。你永远不会展示你是如何定义 editor 的,或者它在地图活动中是否相同。 这将阻塞主线程,但在 startActivity 之前将线程休眠 1000 毫秒,如果 SharedPreferences 仍然没有在另一侧提取更新的数据,那么它不是只是缓慢但破碎。 @JeenbekKhydyr MapsActivity 首先检查这些值,如果它们存在,则地图将显示,否则护士注册活动将显示 【参考方案1】:

这不是将电子邮件和密码存储在 SharedPreferences 中以实际了解用户何时通过身份验证的常用方法。最简单的解决方案是使用我在以下代码中的回答中解释的侦听器:

One time login in app - FirebaseAuth

这样,如果用户没有登录,你可以将用户重定向到LoginActivity,否则重定向到MapActivity。

【讨论】:

嘿@AlexMamo,我尝试了你的答案,但不幸的是这没有帮助,我得到了相同的结果,我知道这不是存储电子邮件和密码的常用方法,但这是为了测试目的。我会更新我的问题,让您知道检查的目的。 我不知道你是如何得到相同的行为的,因为监听器只有在身份验证状态发生变化时才会触发。好的,请随时通知我。 嘿艾哈迈德。一切都好吗?如果您认为我的回答对您有所帮助,请考虑通过单击左侧投票箭头下方的复选标记(✔️)来接受它。应将颜色更改为绿色。我真的很感激。谢谢!

以上是关于共享首选项编辑器需要花费大量时间来提交更改的主要内容,如果未能解决你的问题,请参考以下文章

如何使用android中的共享首选项将数据保存在editText中[重复]

颤振与 setInt 共享首选项问题

来自共享首选项的android数组

Android:从设置外部更改相机权限会导致应用程序共享首选项清除

如何保护 Android 共享首选项?

java 更改摘要共享首选项