无法在OnClick上获得正确的共享质量价值
我目前正在制作一个小应用程序,并且使用OnClick侦听器会停留在更改碎片上。我已经搜索了该网站,并且可以找到类似的情况,但是拟议的解决方案都没有奏效。
因此,当用户登录时,它会使用用于设置和获取共享Preferences值的类中的方法中的共享频率(例如用户名,电子邮件和帐户级别)设置一些值。之后,它应自动将用户重定向到其他片段。没有发生的事情是将用户重定向到另一个片段。
我正在使用asynctask访问数据库。这是我的登录异步箱的代码:
public class LoginSync extends AsyncTask <String, Void, String> {
AlertDialog dialog;
Context context;
String result;
JSONObject jObject;
String username, password;
String jEmail, jLevel;
public LoginSync(Context context){
this.context = context;
}
@Override
protected void onPreExecute() {
dialog = new AlertDialog.Builder(context).create();
dialog.setTitle("Login Status");
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if(result.equals("login")) {
dialog.setMessage("Logged in successfully!");
}else{
dialog.setMessage("Failed to login! Please check username/password.");
}
dialog.show();
}
@Override
protected String doInBackground(String... voids) {
username = voids[0];
password = voids[1];
String connstr = "URL HERE";
try{
URL url = new URL(connstr);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("POST");
http.setDoInput(true);
http.setDoOutput(true);
OutputStream ops = http.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(ops, StandardCharsets.UTF_8));
String data = URLEncoder.encode("username","UTF-8")+"="+URLEncoder.encode(username,"UTF-8")
+"&&"+URLEncoder.encode("password","UTF-8")+"="+URLEncoder.encode(password,"UTF-8");
writer.write(data);
writer.flush();
writer.close();
ops.close();
InputStream ips = http.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(ips, StandardCharsets.ISO_8859_1));
String line;
while((line = reader.readLine()) != null){
jObject = new JSONObject(line);
result = "false";
if (jObject != null){
jEmail = jObject.getString("email");
jLevel = jObject.getString("account_level");
result = "login";
}
}
if(result.equals("login")) {
AppPreferences.setUserInfo(context.getApplicationContext(), username,jEmail,jLevel);
AppPreferences.setLoggedStatus(context.getApplicationContext(), true);
}
reader.close();
ips.close();
http.disconnect();
return result;
}catch (MalformedURLException e){
result = e.getMessage();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return result;
}
}
使用调试器,我看到这些值正在按照共享频率中的预期设置。但是,在登录片段的OnClick检查中,将其设置为false,直到OnClick方法结束为止。
这是我的登录片段代码:
public class LoginFragment extends Fragment {
private FragmentLoginBinding binding;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = FragmentLoginBinding.inflate(inflater, container, false);
View root = binding.getRoot();
binding.btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final String user = binding.username.getText().toString().trim();
final String pass = binding.password.getText().toString().trim();
LoginSync login = new LoginSync(getActivity());
login.execute(user,pass);
if(AppPreferences.getLoggedStatusBool(getActivity()).equals(true)){
NavHostFragment.findNavController(getParentFragment()).navigate(R.id.action_nav_login_to_nav_home);
}
}
});
binding.lnkRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
NavHostFragment.findNavController(getParentFragment()).navigate(R.id.action_nav_login_to_nav_register);
}
});
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
在第一次单击时,值正确设置了值,但是在运行异步之后,使用调试器检查onclick,告诉我它仍然是错误的,并且不会触发if子句中的片段更改。在第二次点击中,它更改了片段。
我在做什么错?我该如何使其更改与设置信息相同的点击片段?
谢谢。
I'm currently making a small app and I'm getting stuck on changing fragments using an onClick listener. I've searched the site and could find similar situations, but none of the proposed solutions worked.
So, when a user logs in, it sets a few values in SharedPreferences such as username, email and account level using a method from a class used to set and get SharedPreferences values. Afterwards, it should automatically redirect the user to a different Fragment. What's not happening, is redirecting the user to the other fragment.
I'm using AsyncTask for accessing the database. This is my code for the Login AsyncTask:
public class LoginSync extends AsyncTask <String, Void, String> {
AlertDialog dialog;
Context context;
String result;
JSONObject jObject;
String username, password;
String jEmail, jLevel;
public LoginSync(Context context){
this.context = context;
}
@Override
protected void onPreExecute() {
dialog = new AlertDialog.Builder(context).create();
dialog.setTitle("Login Status");
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if(result.equals("login")) {
dialog.setMessage("Logged in successfully!");
}else{
dialog.setMessage("Failed to login! Please check username/password.");
}
dialog.show();
}
@Override
protected String doInBackground(String... voids) {
username = voids[0];
password = voids[1];
String connstr = "URL HERE";
try{
URL url = new URL(connstr);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("POST");
http.setDoInput(true);
http.setDoOutput(true);
OutputStream ops = http.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(ops, StandardCharsets.UTF_8));
String data = URLEncoder.encode("username","UTF-8")+"="+URLEncoder.encode(username,"UTF-8")
+"&&"+URLEncoder.encode("password","UTF-8")+"="+URLEncoder.encode(password,"UTF-8");
writer.write(data);
writer.flush();
writer.close();
ops.close();
InputStream ips = http.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(ips, StandardCharsets.ISO_8859_1));
String line;
while((line = reader.readLine()) != null){
jObject = new JSONObject(line);
result = "false";
if (jObject != null){
jEmail = jObject.getString("email");
jLevel = jObject.getString("account_level");
result = "login";
}
}
if(result.equals("login")) {
AppPreferences.setUserInfo(context.getApplicationContext(), username,jEmail,jLevel);
AppPreferences.setLoggedStatus(context.getApplicationContext(), true);
}
reader.close();
ips.close();
http.disconnect();
return result;
}catch (MalformedURLException e){
result = e.getMessage();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return result;
}
}
Using the debugger, I see that the values are being set as intended in the SharedPreferences. However, in the onClick check on the Login Fragment, it's set to false until the onClick method ends.
This is my Login Fragment code:
public class LoginFragment extends Fragment {
private FragmentLoginBinding binding;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = FragmentLoginBinding.inflate(inflater, container, false);
View root = binding.getRoot();
binding.btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final String user = binding.username.getText().toString().trim();
final String pass = binding.password.getText().toString().trim();
LoginSync login = new LoginSync(getActivity());
login.execute(user,pass);
if(AppPreferences.getLoggedStatusBool(getActivity()).equals(true)){
NavHostFragment.findNavController(getParentFragment()).navigate(R.id.action_nav_login_to_nav_home);
}
}
});
binding.lnkRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
NavHostFragment.findNavController(getParentFragment()).navigate(R.id.action_nav_login_to_nav_register);
}
});
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
On the first click, the values are set correctly, but checking the onClick with the debugger tells me that it's still false, after running the AsyncTask, and it doesn't trigger the fragment change in the if clause. On the second click, it changes the fragment.
What am I doing wrong? How can I make it change the fragment on the same click as it sets the information?
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您从共享的股票中获得正确的值,只有获得该值的时间是不正确的。您正在使用在其他线程上工作的异步任务。在您的单击中,您有以下行:
您必须假设您的IF语句将在完成登录异步任务后执行,但这不会发生,它将在启动登录过程后直接执行,并将在值为值之前检查sharedpref甚至设置。您正在进行网络调用和IO操作,该操作将需要一些时间,并且在完成异步任务后应检查共享的PEEF。因此,您应该在Async类的OnPostExecute方法中写下您的IF语句:
You are getting correct value from sharedPreference, only your timing to get that value is not correct. You are using async task, which works on a different thread. in your onCLick you have these lines:
you must have assumed that your if statement will execute after your login async task is completed, but this will not happen, it will execute straight after starting the login process and will check the sharedPref before the value is even set. You are doing network call and IO operation which will take some time and shared pref should be checked after the async task has been completed. So yo should write your if statement in async class's onPostExecute method like this: