我目前正在制作一個小型應用程式,但我被困在使用 onClick 偵聽器更改片段上。我已經搜索了該站點,并且可以找到類似的情況,但是所提出的解決方案都沒有奏效。
因此,當用戶登錄時,它會使用用于設定和獲取 SharedPreferences 值的類中的方法在 SharedPreferences 中設定一些值,例如用戶名、電子郵件和帳戶級別。之后,它應該自動將用戶重定向到不同的 Fragment。沒有發生的是將用戶重定向到另一個片段。
我正在使用 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;
}
}
使用除錯器,我看到這些值是按照 SharedPreferences 中的預期設定的。但是,在登錄片段的 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 告訴我在運行 AsyncTask 后它仍然是錯誤的,并且它不會觸發 if 子句中的片段更改。在第二次單擊時,它會更改片段。
我究竟做錯了什么?如何使它在設定資訊的同時單擊更改片段?
謝謝你。
uj5u.com熱心網友回復:
您從 sharedPreference 中獲得了正確的值,只是您獲得該值的時間不正確。您正在使用異步任務,該任務在不同的執行緒上作業。在您的 onCLick 中,您有以下幾行:
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);
}
您必須假設您的 if 陳述句將在您的登錄異步任務完成后執行,但這不會發生,它將在啟動登錄程序后直接執行,并會在設定值之前檢查 sharedPref。您正在進行網路呼叫和 IO 操作,這將需要一些時間,并且應在異步任務完成后檢查共享首選項。所以你應該在異步類的 onPostExecute 方法中撰寫你的 if 陳述句,如下所示:
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if(result.equals("login")) {
dialog.setMessage("Logged in successfully!");
if(AppPreferences.getLoggedStatusBool(getActivity()).equals(true)){
NavHostFragment.findNavController(getParentFragment()).navigate(R.id.action_nav_login_to_nav_home);
}
}else{
dialog.setMessage("Failed to login! Please check username/password.");
}
dialog.show();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/496427.html